stefanv

332 Reputation

7 Badges

15 years, 98 days

Stefan Vorkoetter is a Senior Architect at Maplesoft, a position that is a combination of design consultant and developer-at-large.

He has been with Maplesoft since May of 1989 after completing a graduate program at the University of Waterloo under Maplesoft co-founder Gaston Gonnet. During his undergraduate career, he worked part time at UW's Symbolic Computation Group, where the Maple system was born.

Stefan's areas of expertise are in algorithms, data structures, and programming language design and implementation. He has worked extensively on various aspects of the Maple kernel, and more recently, the Modelica compiler component of MapleSim. Despite holding a Master of Mathematics degree, he considers himself a computer scientist first.

Stefan was born in Germany, but immigrated to Canada at the age of three. Like many at Maplesoft, he moved to Waterloo to attend the University of Waterloo, met his wife there, and never left. When not working, Stefan is an active participant in the Norwegian Fjordhorse farm he and Lori call home. He also dabbles in electronics, model and full-scale aviation, music, and collecting slide rules and old calculators, and maintains a web site documenting his hobbies.

MaplePrimes Activity


These are replies submitted by stefanv

@Carl Love I've clarified this in the help pages for the next major release.

@radaar

An assignment with the same uninitialized variable on both sides is an infinite recursion. Note that the assginment to i outside of the procedure has no effect on the issue. That assigns to the global i, which is not the same variable as the local i.

This is not a problem inside the procedure, because evaluation there is only ever done one level deep. Thus, i is assigned the value i+2, and all is well.

Once you evaluate the expression outside of any procedure, evaluation is done to the full depth of the expression. Thus i is evaluated to i+2, then the i and 2 in that result are evaluated. So, i is evaluated to i+2 again, and then the i and 2 are evaluated again, ad infinitum. Eventually, Maple runs out of stack space and gives the error you are seeing.

This may not help in deciding what terminology to use for the bound variable of seq (or add or mul), but it may help in understanding what is going on ...

The bound variable is actually the instance of the variable currently in scope when seq is invoked. For a call at the top level, the global variable is used. For a call within a procedure, the procedure's local variable is used (it is quietly implicitly declared local if one wasn't declared). The "magic" is that the value of the variable is saved before the seq is carried out, and restored afterwards. The following sessions illustrates this:

> a := 42;
                                    a := 42

> f := proc() global a; print(a); a end:

> seq(f(), a=1..3);
                                       1

                                       2

                                       3

                                    1, 2, 3

> a;
                                      42

Here we can see that a local is implicitly declared:

> g := proc(n) seq(i,i=1..n) end;
                 g := proc(n) local i; seq(i, i = 1 .. n) end

The quiet implicit declaration of the local was introduced in the last few years. In older versions of Maple, the global variable would be used if no local with the same name was present.

Regardless of whether you use time or CodeTools:-Usage, the reported CPU time will vary.

  • One factor is the granularity of the clock itself, so results can easily vary +/- 1 minimum measurable time interval depending on the points within a time interval that a computation started and finished.
  • System load affect not only real time, but also CPU time due to factors such as effects on the CPU's cache.
  • Maple can ake different execution paths in different orders when the same calculation is run in different sessions and/or structures can be arranged differently in memory, resulting in differences in computation time even though the same result is produced (again, some of this is due to effects on CPU caching).
  • Running the same commands multiple times within the same session will almost always result in different CPU times. Sometimes this can be significantly less due to Maple reusing cached results for part of a computation. Other times, additional memory will be used to rerun the calculation, resulting in more time spent in the garbage collector.

In short, CPU time is deterministic. Running the same large computation repeatedly (in a fresh session each time) should give reasonably consistent CPU times, but they will not be identical.

@Carl Love

Your Wirth syntax diagram for the second form (the in form) is incorrect: The for clause is actually optional.
Indeed, you are correct. Thanks for pointing it out. I have updated the post accordingly.

If you want a column vector, you can use acer's method above, substituting "column" for "row", or you can use the shorter:

< seq(0..20,0.5) >

The nops function returns the number of operands in an expression (e.g. number of terms in a sum, elements in a list, etc.)  It expects exactly one argument.

You should probably be using strings, not names, to represent your letters and words. The single-letter names D and I both have values in Maple. D is a procedure for computing derivatives, and I is the imaginary unit. You can probably get away with D due to last name evaluation, but I evaluates to Complex(1), so that is what gets passed to the 9th call of CountCharacterOccurences instead of the symbol.

> print(D);
proc(f::{array, list, set, algebraic, equation, procedure, appliable_module})
     ...
end

> print(I);
                                           I

> dismantle(I);

COMPLEX(2)
   INTPOS(2): 1

... to store your 9(92) results, as Carl pointed out. I'm afraid I can't answer your question about how to install on Amazon, but as you can see, doing so for this problem would be pointless.

The most compact way to store a 9×9 matrix with 9 possible elements is as the base-2 representation of an 81-digit base-9 number. That would take 257 bits per matrix since ceil(log[2](9^(9^2))) = 257. So your problem is roughly equivalent to storing all possible 257-bit numbers, of which there are 2257.

A 64-bit architecture with physical memory at every address has 264×8 = 267 bits of memory. So assuming bit-level packing, a single fully equipped 64-bit machine could store 267/257, or about 5.7×1017 of your matrices (ignoring space required for the OS, your program, etc.)

That means you would require 2257/(5.7×1017), or approximately 4×1059, Amazon servers, which is a bit more than 100.

Perhaps there is a better way to solve the underlying problem you are trying to solve?

Indeed, interface(ansi=true) is not meant to be used with the worksheet interface(s). Generally it has no effect, but for a few commands like showstat, it does. In the next release, interface(ansi) will be true by default in Windows, but only in cmaple.

Yes, Windows 2000 and up do not support interpretation of ANSI escape sequences (which is what cmaple used to highlight output). As a result, these escape sequences were visible if interface(ansi=true) was set in cmaple for Windows prior to Maple 2018.1. Starting with cmaple 2018.1 for Windows, we use direct calls to the Windows API for this instead.

@Preben Alsholm The text size of cmaple in Windows is not under cmaple's control. It is just whatever size the Windows command prompt window is set to. To change it, open cmaple, then click on the icon in the top left corner of the window's title bar. Select "Properties", and then the "Font" tab. Here you can choose from a limited selection of fonts, and also the size you want. After closing the dialog, exit cmaple so that the settings are saved. The next time you open cmaple, your new settings should still be in effect.

You are correct about highlighting not being on by default in Windows. I was using the version of Maple currently under development, where it now is on by default. I have updated the article accordingly.

@nm

For the situation you describe ("I want to iterate over the list and make some substituion to each entry if needed"), you should encode your substitution algorithm into a procedure (perhaps an anonymous one) and map that over the list or set. This is efficient, as only one new list or set is constructed (the one containing all the modifications). Here's a cooked up example:

S := {seq(i,i=1..1000)}; # Generate a set of integers.
# Square the odd ones.
S := map(proc(x) if x::odd then x^2 else x fi end, S);

Simple "one-liner" procedures like the one above can be written in a more compact notation too:

S := map(x -> if x::odd then x^2 else x fi, S);

Internally, Maple creates a new expression sequence the same size as the one in the original set, applies your procedure to each in turn, in-place, and then turns that back into a set (re-ordering, removing duplicates that may have resulted, etc.).

Note that the example above could not have been written using substitution into the set, whether by the non-existent S[i] := expr syntax, nor using subsop. After each substitution was completed, the set would be resimplified, and likely reordered, and the remaining elements not yet processed would no longer be in their original locations:

Using map:

> S := {seq(i,i=1..10)};                                                               
                         S := {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

> S := map(x -> if x::odd then x^2 else x fi, S);                                      
                        S := {1, 2, 4, 6, 8, 9, 10, 25, 49, 81}

Using a loop (I've added a print statement in the loop so we can see why we're going to get an error):

> S := {seq(i,i=1..10)};                                                               
                         S := {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

> for i to 10 do                                                                       
>     if S[i] :: odd then                                                              
>         S := subsop(i=S[i]^2,S);                                                     
>         print(S)                                                                     
>     fi                                                                               
> od:                                                                                  
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

                             {1, 2, 4, 5, 6, 7, 8, 9, 10}

                             {1, 2, 4, 6, 7, 8, 9, 10, 25}

                            {1, 2, 4, 6, 8, 9, 10, 25, 49}

                            {1, 2, 4, 6, 8, 10, 25, 49, 81}

                           {1, 2, 4, 6, 8, 10, 49, 81, 625}

                          {1, 2, 4, 6, 8, 10, 49, 625, 6561}

                        {1, 2, 4, 6, 8, 10, 49, 625, 43046721}

Error, invalid subscript selector

Notice that the second time we square an entry, 3, it becomes 9, and there is now one less member in the set (because there was already a 9). Furthermore, when we square 5 and replace it with 25, the 25 ends up at the "end" of the set in the underlying data structure, so later we encounter the 25 and square it as well (since it's also odd). Finally, we get an error when accessing the no-longer present 10th element of the set (the one that was lost when we squared 3).

Yes, the original plot code was written in the summer of 1986. I worked for SCG that summer, and wrote the driver side of the code (in C), and Alan Donsig (sp?) wrote the first version of the library side (in Maple).

Stefan Vorkoetter - Maplesoft

Regarding the importing of pictures, there's always ImageTools:-Read. If you want to combine a Maple plot with a photograph, for example, you can export the plot into one of the image formats supported by ImageTools, then read that and your other image in, and then programmatically combine them.

Samir, I haven't looked at the code, but did you take into account that the latitude-longitude grid is not square? At our latitude of about 45 degrees, the width of one degree of longitude is only about 0.7 times the height of one degree of latitude. For any latitude L, the spacing of the longitude lines is cos(L) times the spacing of the latitude lines (so at the equator, latitude and longitude are square, while at the poles, the longitude lines are all coincident).

Stefan

1 2 Page 1 of 2