acer

32333 Reputation

29 Badges

19 years, 322 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

eval(G(X1,X2,1),G=M1);

The `subs` command does syntactic substitution, without subsequent evaluation. It is often (mis)used in situations where `eval` is the more appropriate command. See both the first and the last paragraphs of the ?subs help-page's Description section.

acer

Regardless of which optimization command is used (eg. The DirectSearch or Optimization packages), the whole operation's timing performance will depend very much on the speed of each individual evaluation of the objective function.

On a mid-range Core2 Duo, the original code posted (as a follow-up comment in this thread) took about 13.5 seconds for a single objective function evaluation.

In the attached worksheet there are a variety of variations on re-coding the objective procedure. The best timing seems to be about 0.5 to 0.75 seconds on that same Core2 Duo.

I added some notes, hopefully illustrating in steps how some realizations and improvements came about, from variant to variant. (It needs the .xls data linked in that follow-up comment.)

F2proc_newer.mw

Note that there is one potential issue with the code that I ought to mention. In the original EIGEXP, the `res` Vector is created with size 1971, and 1971 elements are used from At and TC. But only 1969 elements of `res` are used to form the sum of squares. I presume that the OP knows what's going on with that, and can sort it out if necessary.

I only tested a smattering of individual points. A more thorough check of results between implementations could be done. Small variations past the 10th digit or so are expected, due to Digits, evalhf uses, etc.

acer

If you upload a worksheet containing the code then we might be able to speed up its objective function evaluations.

acer

> ee:=sin(x)^4/cos(x)^2;

4
sin(x)
-------
2
cos(x)

> eval(ee,cos=sin/tan);

2 2
sin(x) tan(x)

acer

Tell us just exactly how you'd do it by hand, and we could tell you how to do those steps in Maple.

(Alternatively, someone might just give you the answer in spiffy syntax, which won't help you much for the next time...)

acer

Something simple like this might do for you.

ASTEM97:=module()
option package;
export psat;
local ModuleLoad;
ModuleLoad := proc()
local dllloc;
dllloc := "c:/Windows/system/astemdll.dll";
psat := define_external('psat97mc', 'FORTRAN',
'arg1'::('float[8]'),
'RETURN'::('float[8]'),
'LIB' = dllloc);
# repeat for other exports
NULL;
end proc;
end module:
libname:="c:/TEMP",libname:
LibraryTools:-Create("c:/TEMP/astem97.mla");
savelib(ASTEM97);

The material above only needs doing once, each time you adjust and create the thing. Typically, you would save this build code in a worksheet or text file, so that you could rebuild it as you add more exports, etc. Note that the ModuleLoad routine only runs when the module is read from an .mla archive into a new session. So it won't run in this session, until you restart.

The next part below, after the restart, ie., the setting of libname, can be done in each new session prior to the with(). Or you can adjust the libname in your maple initialization file.

> restart:
> libname:="c:/TEMP",libname:
> with(ASTEM97);

Or you could move the created .mla file to a folder (new, you have to create it in your OS) such as what gets returned by the Maple command,

   cat(kernelopts(homedir),"\\maple\\toolbox\\14\\ASTEM97\\lib");

and then close the GUI and relaunch. Replace the "14" with your Maple version number.

Of course, since I don't have that .dll then all I get is,

> with(ASTEM97);
Error, external linking: error loading external library c:/Windows/system/astemdll.dll: The
specified module could not be found.

You can get fancy, wrapping the define_external calls in try..catch statements if you want it to do something special upon failure. But perhaps try the simple stuff first.

acer

On Windows 7 by default it is C:\\Users\<username>\Desktop

And on Windows XP and Windows 2000 by default it is C:\\Documents and Settings\<username>\Desktop

Even better, C:\\Users\<username> can be attained by the Maple command kernelopts(homedir) on Windows 7. And by default that command produces C:\\Documents and Settings\<username> on Windows XP/2000.

So this sort of thing should hopefully work for you, on any of XP/2000/7

> F := cat(kernelopts(homedir),"\\","Desktop\\foo.txt"):

> readdata(F,2);

                 [[4., 3.], [5., 6.], [7., 8.]]

> H := cat(kernelopts(homedir),"\\","Desktop\\"):

> readdata(cat(H,"foo.txt"), 2);

                 [[4., 3.], [5., 6.], [7., 8.]]

See here for more on home directories across operating systems.

acer

It might be a good idea to read some other word list (into a Maple list), rather than rely on the built-in pattern dictionary. It seems a little small, as indicated below by the examples which return NULL instead of returning at least the input string.

> with(StringTools): with(PatternDictionary):
> bid:= Create(`builtin`):
> words:= [seq](Get(bid,i),i=1..Size(bid)-1):

> Anagrams("nru",words);
                          "run", "urn"

> Anagrams("aterapse",words);
                           "separate"

> Anagrams("separates",words);

> Anagrams("redeem",words);

> Anagrams("modality",words);

> Anagrams("sparsity",words);

It was not hard to find missing words. Of course, you could still use StringTools:-Anagram, to find all anagrams of your input string in the given word list.

acer

Regarding your question 2, the idea seems premature in the sense that there are several other less difficult (but still difficult) requirements that would have to come first.

The big deal about high end GPUs is that they have lots of processing cores, and so are great for highly parallelizable tasks. Some (but not all) symbolic computation falls into that category. That qualification may be narrowed further as the full potential of general purpose graphical processing units (GPGPUs) appears more for floating-point computation, while much of Maple's symbolic computation involves integers and memory pointers (viz. DAGs).

In order to use a GPU for symbolics one would likely have to take something like one of the following paths:

A) make the interpreted Maple library thread-safe, port the kernel interpreter to the GPGPU runtime using efficient thread-supporting memory management, solve the problem of memory communiation latency to/from the GPGPU, solve other nasty issues I haven't thought of...

B) write a maple compiler that can handle exact symbolic maple language code, have that compiler emit thread-safe compiled code(!) with efficient thread-supporting memory management(!), make that compiler emit object code that can run on the GPGPU, solve the problem of memory communiation latency to/from the GPGPU, solve other nasty issues I haven't thought of...

It would be very nice to have just the first item in each of A) and B) along with a memory management system that handles threads well, even without regarding GPUs at all. The true power of the Maple Threads system which already exists for writing code to execute in parallel really could benefit from a thread-safe interpreted system Library and such a garbage collector. And a maple compiler that could handle symbolics would best the interpreted runtime , for even just serial calculations. None of these things is likely to be easy.

I think that a better, feasible short-term goal for GPGPUs under Maple could be a more general framework for numeric calculation on the GPU. By that I mean not merely a few (or even many) pre-made numeric routines like for FFTs, numeric pdes, linear algebra, etc. I mean for "user-defined" procedures. Such functionality might cover both custom procs for linear algebra computation (the data should all be pushed to the card once, at the start, and returned once at the end -- none of this up-down repeatedly for each stock GPU-capable command). Another nice piece of functionality would be for populating a data array -- push up a data rtable and a result rtable along with a compilable function with which to do a mapped populating job. That could be great for producing big 3D plots structures, assuming those could be just float[8] rtables.

acer

There's no easy way to get the error message to display the line number of the procedure in which an error occurs (without at least unprotecting and redefining the `error` command).

But for Library routines (ie. not kernel built-in commands) there is tracelast. For example,

> fsolve({x*y},x);
Error, (in fsolve) y is in the equation, and is not solved for

> tracelast;
 fsolve called with arguments: {x*y}, x
 #(fsolve,166): error "%1 is in the equation, and is not solved for", op(r)
Error, (in fsolve) y is in the equation, and is not solved for
 locals defined as: _X = x, eqns = {x*y}, eqns2 = eqns2, neqs = neqs, i = i, indx = indx, opt = opt, r = {y}, s = s, sol = sol, t = x, tvars = {x}, t1 = t1, ans = ans, temp = {}, procL = false, loceqs = loceqs, is_set = is_set, extra = ()

One can check that output, using `showstat` itself,

> showstat(fsolve,166);

fsolve := proc(eqs, vars)
local _X, eqns, eqns2, neqs, i, indx, opt, r, s, sol, t, tvars, t1, ans, temp, procL, loceqs, is_set, extra;
       ...
 166       error "%1 is in the equation, and is not solved for", op(r)
       ...
end proc

acer

Firstly, one might more normally use `mul` not `product` for multiplying together a finite number of terms.

But more relevant here is that `mul` is going to use `*`, and not the noncommutative `.` which is more what one wants for multiplying Matrices.

> <<1,2>|<3,4>> * <<5,6>|<7,8>>;
Error, (in rtable/Product) invalid arguments
> <<1,2>|<3,4>> . <<5,6>|<7,8>>;
                                  [23  31]
                                  [      ]
                                  [34  46]

Fortunately, `.` is not only a binary infix operator (eg. A . B) but is also an n-ary prefix operator (eg. `.`(A,B,C,E,...)) for an arbitrary finite number of arguments.

You could try this, then,

`.`(seq(MatrixExponential(I*Matrix(d,{(l,l)=1})*A[l,l]),l=1..d));

(I'm deliberately leaving aside discussion of how the final result of your particular example might be more easily obtained, as you could likely figure that out right away after seeing the result. I presume that this is merely a toy example to illustrate the issue with using `product`.)

acer

Suppose that one has a file foo.txt whose first line is this,

"C:\\TEMP\bar.txt" 13 gg

That can be scanned, and the first column's item (the string) converted, as follows,

> restart:
> fclose("C://TEMP/foo.txt");

> P:=fscanf("C://TEMP/foo.txt","%s %a %a");
[""C:\\TEMP\bar.txt"", 13, gg]

> # Make every \ into /
> StringTools:-SubstituteAll(P[1],"\\","/");
""C://TEMP/bar.txt""

> # Alternatively, make both \\ and \ into //
> StringTools:-SubstituteAll(P[1],"\\\\","//"):
> StringTools:-SubstituteAll(%,"\\","//");
""C://TEMP//bar.txt""

That last example should also cover the case of "c:\data\...", turning it into "c://data//..."

acer

Maple does contain a dictionary, but it also has a lot of jargon (ie. Maple, math) words in it.

> with(StringTools):
> with(PatternDictionary):

> dict:=Create('builtin'):
> L:=select(IsLower,select(IsAlpha,[seq](Get(dict,i),
>                                        i=1..Size(dict)-1))):

> twoletterwords:=select(z->length(z)=2,L);

 ["ad", "ah", "am", "an", "as", "at", "ax", "be", "by", "cf", 

   "do", "du", "eh", "el", "em", "en", "et", "ex", "go", "ha", 

   "he", "hi", "ho", "if", "ii", "in", "is", "it", "iv", "ix", 

   "la", "ln", "lo", "ma", "me", "mi", "mu", "my", "ne", "no", 

   "nu", "of", "oh", "on", "or", "ow", "ox", "pa", "pi", "re", 

   "sa", "so", "ti", "to", "up", "us", "vi", "we", "xi", "ye"]

> t2 := "abc": t3 := "def": t4 := "ghi": t5 := "jkl":
> t6 := "mno": t7 := "pqrs": t8 := "tuv": t9 := "wxyz":

> findem := proc(a,b)
> local T, numfound, thist, sol;
>    T:=combinat:-cartprod([[LengthSplit(a,1)],
>                           [LengthSplit(b,1)]]):
>    numfound:=0:
>    while not T[':-finished'] do
>       thist := cat(op(T[':-nextvalue']()));
>       if member(thist,twoletterwords) then
>          numfound:=numfound+1;
>          sol[numfound]:=thist;
>       end if;
>    end do:
>    convert(sol,list);
> end proc:

> findem(t4,t7);
                                   ["is"]

> findem(t2,t6);
                                ["am", "an"]

> findem(t3,t6);
                             ["do", "em", "en"]

That is by no means especially efficient. (For one thing, you could just make t2, t3, etc, into actual lists of single-characters, so that the procedure wouldn't ever have to split them more than once.)

acer

As shown in response to your duplicate post, you can specify a global solver for Optimization:-Maximize.

In this example, it may happen that the default local solver used by Maximize also returns the global maximum. But you can also force the method, with an option.

> with(Optimization):

> nx := Maximize(abs(.5547114632*x^2+1.130478381*x+.9883691714-exp(x)),
               x = -1 .. 1, method=branchandbound);

            nx := [0.0456887233851495, [x = -0.436328905794407]]

acer

For some reason, Maximize is using its "local" solver on this problem by default.

> restart:

> with(Optimization):

> infolevel[Optimization]:=1:

> nx := Maximize(
>         abs(.5539395590*x^2+1.130864333*x+.9891410756-exp(x)),
>         x=-1.0..1.0); # "local solver"

NLPSolve: calling NLP solver
NLPSolve: using method=quadratic
NLPSolve: number of problem variables
            nx := [0.0452333936742979, [x = -0.438621263028586]]

> nx := Maximize(
>         abs(.5539395590*x^2+1.130864333*x+.9891410756-exp(x)),
>         x=-1.0..1.0,method=branchandbound); # "global solver"

NLPSolve: calling NLP solver
NLPSolve: using method=branchandbound
NLPSolve: number of problem variables
             nx := [0.0454683311488107, [x = 0.560938672728197]]

acer

First 281 282 283 284 285 286 287 Last Page 283 of 336