Carl Love

Carl Love

28100 Reputation

25 Badges

13 years, 103 days
Himself
Wayland, Massachusetts, United States
My name was formerly Carl Devore.

MaplePrimes Activity


These are replies submitted by Carl Love

@vv If you use a module, then the inner procedures only need to be "compiled" (or parsed) once; whereas if you use nested procedures, then the inner procedures need to be compiled on every run of the outer procedure. Also, with the module, the initializations only need to be done once. You can see this by including

local dummy:= print("Initializing now.");

in each.

I automatically think of modules whenever I need a variable that can't be global and can't be local to the inner procedure. In this case, node is such a variable.

My module can be simplified a little, and I would've done so if I'd thought of it at the time. Your procedure can be simplfied likewise.

#Test case generator, anonymous-procedure version
MakeTreeTable:= module()
local
   i, node,
   nextnode:= proc() node:= node+1 end proc,      
   ModuleApply:= proc(depth::nonnegint, width::nonnegint)
      node:= 0;
      proc(depth :: nonnegint, width :: nonnegint)
         if depth = 0 then nextnode()
         else table([seq(nextnode()=thisproc(depth-1,width), i=1..width)]);
         end if
      end proc
      (depth, width)
   end proc
;
end module:

Although some people have a stylistic objection to explicitly invoked anonymous procedures.

@emendes Yes, you're using the term monomial correctly.

I only have a vague idea of what you're talking about. Are you saying that you want all the subsets of a certain set that contain the element x*y*theta[5]? It'd help my understanding if you'd use mathematical terms such as set and subset.

It's very likely that what you want can be done by the Iterator package in such a way that all the objects don't need to be created at once. If you want all the subsets as I described in the first paragraph, then certainly it can be done.

@Joe Riel In the worksheet below, I made three changes to the tests:

  • I made some perhaps-trivial-seeming modifications to your procedure TableTest that add up to a significant time savings.
  • I created a better test case generator by modifying your MakeTable so that it doesn't repeat the indices. This is so that the procedures being tested will have a more-realistic amount of garbage collection.
  • I created a wrapper for CodeTools:-Usage that more accurately accounts for the garbage collection.

(Sorry, the worksheet uploading is not working for me.)

restart:

#Carl's original nested-table equality tester
TableToSet:= T-> `if`(T::table, {op(2, thisproc~(T))[]}, T):
TablesEqual:= (A::table, B::table)-> 
   evalb(TableToSet(A) = TableToSet(B))
:

#Joe's original nested-table equality tester
TableTest1:= proc(a := NULL, b := NULL)
local aindx, bindx;
    if a::table and b::table then
        aindx := {indices(a)};
        bindx := {indices(b)};
        aindx = bindx and andmap(i->TableTest1(a[op(i)],b[op(i)]), aindx);
    else
        evalb(a = b);
    end if;
end proc:

#Joe's procedure with some small modifications by Carl
TableTest2:= proc(a, b)
local aindx;
    if a::table and b::table then
        aindx := [indices(a, 'indexorder')];
        aindx = [indices(b, 'indexorder')] and andmap(i-> TableTest2(a[i[]],b[i[]]), aindx);
    else
        a = b;
    end if;
end proc:

#Test case generator
MakeTreeTable:= module()
local
   i, node,
   nextnode:= proc() node:= node+1 end proc,      
   MakeTable:= proc(depth :: nonnegint, width :: nonnegint)
      if depth = 0 then nextnode()
      else table([seq(nextnode()=thisproc(depth-1,width), i=1..width)]);
      end if
   end proc,
   ModuleApply:= proc(depth::nonnegint, width::nonnegint)
      node:= 0;
      MakeTable(depth, width)
   end proc
;
end module:

#Wrapper for CodeTools:-Usage that more accurately accounts for garbage collection
TimeTest:= module()
export output;
local
   #I read once that it takes 4 gc()s to collect all garbage. Some confirmation
   #of that would be welcome.
   gc4:= proc() to 4 do gc() od end proc,
   TestWithGC:= proc(Code::uneval)
      output:= CodeTools:-Usage(Code);
      CodeTools:-Usage(gc4()); #End test by collecting the garbage that the test made.
      output
   end proc,
   ModuleApply:= proc(Code::uneval)
      gc4(); #Start test with a fresh slate.
      CodeTools:-Usage(TestWithGC(Code))
   end proc
;
end module:

#Equal test cases
(A,B):= 'MakeTreeTable(5,10)' $ 2:

TimeTest(TableTest2(A,B));
memory used=33.40MiB, alloc change=256.00MiB, cpu time=547.00ms, real time=536.00ms, gc time=78.12ms
memory used=16.44KiB, alloc change=0 bytes, cpu time=344.00ms, real time=244.00ms, gc time=328.12ms
memory used=33.47MiB, alloc change=256.00MiB, cpu time=891.00ms, real time=782.00ms, gc time=406.25ms
                              true
TimeTest(TableTest1(A,B));
memory used=45.09MiB, alloc change=0 bytes, cpu time=735.00ms, real time=623.00ms, gc time=171.88ms
memory used=16.39KiB, alloc change=0 bytes, cpu time=312.00ms, real time=237.00ms, gc time=296.88ms
memory used=45.15MiB, alloc change=0 bytes, cpu time=1.05s, real time=860.00ms, gc time=468.75ms
                              true
TimeTest(TablesEqual(A,B));
memory used=84.59MiB, alloc change=32.00MiB, cpu time=500.00ms, real time=437.00ms, gc time=125.00ms
memory used=16.34KiB, alloc change=0 bytes, cpu time=344.00ms, real time=286.00ms, gc time=312.50ms
memory used=84.64MiB, alloc change=32.00MiB, cpu time=844.00ms, real time=723.00ms, gc time=437.50ms
                              true

 

@sand15athome You now have a reputation of 15 on the account sand15athome, so you should be able to vote up.

@emendes Ah. The cyclic dependency error must be a bug in Maple 14, because obviously there is no cyclic dependency.

I simplified the code of the procedure a little:

MyTest:= (
   F::list(algebraic), 
   V::And(list(name), satisfies(V-> nops(V)=nops(F)))
)->
   andmap(
      k-> ormap(depends, [F[..k-1][], F[k+1..][]], V[k]),  
      {$1..nops(V)}
   )
:

 

@Ronan The control to insert formatted code is the rightmost button on the second row of the toolbar in the editor. It looks like < > on top of a dog-eared piece of paper.

Tom Leslie also can't upload worksheets.

@vv I don't know about it being more-efficient computerwise, but it's much easier for me to think about multi-indices than nested tables. So perhaps it's more efficient brainwise.

My untested guess is that multi-indices would be a little bit less efficient computerwise because the indices need to be formed, then garbage-collected, as sequences.

I have an idea about constructing a time test of this, but I need to go right now, so I'll continue this later.

It is quite a chore to read through and edit your code, simply because it is not formatted. Please present your code with some reasonable style of indentation and line breaking. The error that you describe would be quite easy to find if the code was formatted. And please omit the prompts > from your code. It is also a chore for us to remove those.

@emendes They're polynomials.

I'm not familiar with the "cyclic" error. Can you post the exact error message so that I can fix it for Maple 14?

@Preben Alsholm The full Active Comversations page does seem to get updated immediatey. However, that's always another scroll, click, and page refresh away after you've deleted spam. Upon finishing deletion, it now takes you to the MaplePrimes home page. I don't like that. I'd like it to take you to the Active Conversations page immediately.

You can't extrapolate a numeric BVP solution outside its original boundary points.

@Mac Dude You wrote:

  • I don't think there is a direct way to enforce several parameters to have the same type but allowing different types.

You can control the relationship between procedure parameters by using the parameter modifier depends (which has no relationship to the command depends). See ?parameter_modifiers.

@Joe Riel It takes several minutes for the link to disappear, which means that people will waste even more time by deleting spam that's already been deleted.

On the plus side, I like the code snippet feature, and I think that it works better than the equivalent feature on StackExchange. Now I don't need to worry about spacing between my lines of code.

@Ronan Joe's procedure is not effective. There's a great variety of illegal input that it allows. For example:

myproc([a,b], [c,d], [e,<f>]);
myproc(<1,2,3>, <4,5>, <6>);

To answer the thing that you didn't understand: It works because a listlist is not just a list of lists: each sublist is required to have the same number of elements.

Here's a corrected version of Joe's procedure.

myproc := proc(A,B,C)
local L;
     L := [A,B,C];
     if L :: 'list(algebraic)' then
          # option 1
     elif L :: list([algebraic $ 2]) then
          # option 2
     elif L :: list([algebraic $ 3]) then
          # option 3
     elif L :: 'list(Vector(2, algebraic))' then
          # option 4
     elif L :: 'list(Vector(3, algebraic))' then
          # option 5
     else
          error "unknown types of arguments"
     end if;
end proc:

However, I was under the impression that you wanted the validity of the arguments checked in the procedure header rather than the procedure body. I came up with another way to do that---much simpler than the module method that I posted earlier---and it's posted as my second Answer below.

 

 

First 377 378 379 380 381 382 383 Last Page 379 of 709