acer

32313 Reputation

29 Badges

19 years, 315 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

How about 219978219978219978219978219978

> x:=219978219978219978219978219978:
> length(x);
                               30

> 4*x - parse(StringTools:-Reverse(convert(x,string)));
                               0

Some patterns such as below can be used in a repetitive way.

> for N from 4 to 9 do
>   sol:=Optimization:-Minimize(
>     1,
>     {4*add(X[i]*10^(i-1),i=1..N)=add(X[N+1-i]*10^(i-1),i=1..N),
>     seq(X[i]<=9,i=1..N), X[1]>=1, X[N]>=1},
>     assume=nonnegint, depthlimit=1000, integertolerance=1e-15);
>   x:=add(rhs(sol[2][i])*10^(i-1),i=1..N);
>   print(x,  parse(StringTools:-Reverse(convert(x,string))));
> end do:

                           2178, 8712
                          21978, 87912
                         219978, 879912
                        2199978, 8799912
                       21782178, 87128712
                      217802178, 871208712

acer

This behaviour is documented by the option stoppingcriterion on the Bisection help-page. By default, a relative test between successive x-values is the (only) stopping criterion used. But a function-value test is an alternative stopping criterion that can be specified.

This is part of a Student package, so it is intended to allow the student some means to vary the behaviour and observe effects. That's why it provides alternate behaviour specified by such options.

The default behaviour is a relative test (only) using a default tolerance (both documented),

> restart:
> p:=expand( (x-3)^3 );
3 2
x - 9 x + 27 x - 27

> Student:-NumericalAnalysis:-Bisection(
> p, x=[0,12],
> output=sequence);

[0., 12.], [0., 6.000000000], [0., 3.000000000],

[1.500000000, 3.000000000], [2.250000000, 3.000000000],

[2.625000000, 3.000000000], [2.812500000, 3.000000000],

[2.906250000, 3.000000000], [2.953125000, 3.000000000],

[2.976562500, 3.000000000], [2.988281250, 3.000000000]

And now, with a function-value stopping criterion,

> Student:-NumericalAnalysis:-Bisection(
> p, x=[0,12],
> output=sequence, stoppingcriterion=function_value);

[0., 12.], [0., 6.000000000], 3.000000000

Thus rests a defense of sorts. Now a counterpoint or two.

There does not appear to be a way to get the exact behaviour that you described, in which both tests are applied at each iteration. But it likely could be made possible if the stoppingcriterion option were to allow a list of criteria to be applied at each iteration. For example, stoppingcriterion=[function_value, relative] could allow more than one test to be applied. With that syntax then at each iteration it would first check the function value for acceptance, and only if that failed then move on to a relative error test.

The documentation could be also improved with respect to what is in effect another stopping criterion it already uses, which is maxiterations the maximal number of allowed iterations. By experiment one can show that maxiterations takes precedence over the listed stoppingcriterion options. For example,

> Student:-NumericalAnalysis:-Bisection(
> p, x=[0,11], output=sequence,
> stoppingcriterion=function_value, maxiterations=2);

[0., 11.], [0., 5.500000000], [2.750000000, 5.500000000]

So that precedence might be documented more painstakingly (read painfully?) clearly.

acer

@mattfred You wrote, "I see no reason why it should change its root finding method in any way or why it should not produce a continous smooth curve..."

 If you are going to construct the RootOf yourself, with those kind of expectations as stated and for a non-polynomial, then you might be better off using the bounding-box option rather than the root-selector option. By which I mean that you should supply some desired range, in which there is at most one root.

For example,

restart:
`&hbar;`,alpha,m0,delta,`&varepsilon;g`,nu:=1,1e-24,-1e18,1,-1,2e-10:
k := (x) -> sqrt(2*m0*x*1.602/(10^19*`&hbar;`^2
*(alpha+1/3*nu^2*(2/(`&varepsilon;g`+2*m0*x*1.602/(10^19*`&hbar;`^2))
+1/(`&varepsilon;g`+delta+2*m0*x*1.602/(10^19*`&hbar;`^2)))))):

g :=  (x, a) -> BesselJ(1, 1/1000000000*k(x)*a):

plot(g(x, 3.5), x = -5 .. 5, y = -1 .. 1);

h := (a) -> RootOf(g(x, a), x, .5):
h_alt := (a) -> RootOf(g(x, a), x, .1 .. 0.9):

Ph := plot(h(a), a = 2 .. 4, y=-2..2, color=red):
Ph_alt := plot(h_alt(a), a = 2 .. 4, y=-2..2, color=green):
plots:-display([Ph, Ph_alt]);

The basic idea is that the RootOf in h_alt(a) has a range (bounding- box) rather than a starting point (root selector). You didn't post the parameters' numeric values, so I had to fiddle them. But hopefully the code above shows (in your Maple 10- as it does in my Maple 14) that the discontinuities in the red plot can be removed as in the green plot. Of course, if you don't have a nonvarying range in which you can expect just a single root then it would get tricker, possibly with a range that depended upon `a`.

I realize that you had already figured out most of that, based upon your original Post. But I wanted to mention that supplying a range which is too narrow will often give `fsolve` difficulty. I know that sounds counter-intuitive, and it likely reflects undesirable behaviour on fsolve's part. (I believe what happens is that when fsolve's internal solving process steps "out of bounds" it immediately gives up, for that initial point. This is not good; convergence might still have attained, inside bounds, and hence that is giving up inappropriately.)

Robert mentioned alternatives to NextZero. You could construct a procedure `R` that repeatedly calls fsolve, using its 'avoid' option, to find all roots in a stated range. Then you could select the root closest to a given value. You could call `R` and supply the most recent (prior) root found. In this way you might be able to produce a continuous curve of computed roots, as the parameter varies. Here's an attempt, which seems to work,

R:=proc(f,x,rng)
   global init;
   local i, found, S, s, closest;
   S := {};
   while not(type(s,'specfunc'(anything,fsolve))) do
      s := fsolve(f,x=rng,'avoid'=S);
      if type(s,numeric) then
         S := S union {x=s};
      end if;
   end do;
   if nops(S)=0 then return 'procname'(args); end if;
   S:=sort(map(rhs,convert(S,list)));
   closest := S[1];
   for i from 1 to nops(S) do
      if abs(S[i]-init) < abs(closest-init) then
         closest := S[i];
      end if;
   end do;
   init := closest;
   closest;
end proc:

init := 0.75:
plot( 'R'(g(x,a), x, 0.1..1.0), a=2..4, y=-2..2 );

Since `plot` itself may jump around when adaptively selecting x-axis values from which to compute, it may be more prudent when using `R` to form a point-plot (possibly displayed with line style) with ordered input values than to merely call `plot` as I did above. That is due to R's reliance on the global `init` and its value as the previous computed root.

acer

There's some interesting bits to be seen in this old (2008) post on the topic.

acer

  from i from 1 to N do
     try
        res[i] := your_attempt;
     catch:
        res[i] := 0;
     end try;
  end do;

acer

Let's go back and look again at your posted code once more. Maybe there is a simple misunderstanding going on.

When you write the following, what did you intend?

     G[1] := fdiff(EIG, [1], [X[1], X[7]]);

Does `EIG` always expect two arguments, or seven arguments? If `EIG` expects seven arguments then you should call `fdiff` like this instead,

     G[1] := fdiff(EIG, [1], [X[1], X[2], X[3], X[4], X[5], X[6], X[7]]);

Note that the Vector argument `X` of `objfgradient` contains the values of the components of the 7-dimensional "point" at which you want the partial derivatives computed numerically. For `EIG` to be called correctly from within `fdiff` then all the seven numerical scalar elements of the point in question would be needed.

As an `fdiff` usage example, if one has a procedure/operator `f` that takes 5 arguments, then numerical estimation of the partial derivative with respect to the third argument -- evaluated at the given point [a,b,c,d,e] would be done with a call like fdiff(f, [3], [a,b,c,d,e]) .

I see now that my original example, of a procedure that takes only two arguments, is ambiguous. The call fdiff(f, [1], [a,b]) could just as easily be misinterpreted as only requiring the first and last argument in that list [a,b]. But in fact all entries of the given point are needed, as fdiff must pass them along when it in turn calls `f`. Sorry for any confusion.

If this is in fact the source of the problem then you'd also need to change the assignment to G[2], etc... Maybe something like this,

objfgradient := proc(X::Vector, G::Vector)
local Xlist, i, m;
   m := op(1,X);
   Xlist := convert(X,list);
   for i from 1 to m do 
      G[i] := fdiff(EIG, [i], Xlist);
   end do;
NULL;
end proc;

acer

Your general question appears to be answered by Preben.

But you might be interested to know that nops() does not return the number of entries (size) of a Vector.

For V:=Vector(7),

> op(1,V);
                               7

> op(2,rtable_dims(V));
                               7

> LinearAlgebra:-Dimension(V);
                               7

> nops(V);
                               3

Having a single command which returns the number of entries for any of Vector, list, array, etc, has been suggested in the past. It would be useful, consistent, and less confusing. (But it cannot be nops, since that already has another purpose for Vector, rtable, etc.)

acer

Combine the two Answers given so far. One of them shows you how to change one file name to another, or how to programmatically generate filenames (or either flavour). The other tells you which command to use to rename an external file.

Use both together, to programmatically rename all the external files.

acer

You can set the prettyprint level to match the output of either the commandline or Classic interfaces. Eg,
interface(prettyprint=1):

acer

I have (32bit) Maple 11.02 installed on a Windows 7 Pro 64bit machine. And its Standard GUI opens and saves worksheets ok, for the few worksheets I tested. The saved worksheets re-open fine in, say, Maple 14.

I expect that you would certainly need to install the upgrade to 11.02 (since a fix for the file-save dialogue on Windows Vista was introduced in the 11.01 upgrade). See this link.

(This is under an account with admin priviledge, if that matters. I don't remember installing it in any "XP mode", but perhaps I've forgotten. Windows 7 asks me whether the Maple kernel should be allowed to communicate over the network, the first time I ran it. I allowed that, since I knew that Maple's kernel normally talks to its interfaces over the loopback network device. That happened for other, recent versions of Maple too, and isn't a big deal.)

acer

One can now use the read command from within the Standard GUI. And $include directives can be used within the .mpl text source file that gets read.

This is how I usually lay out the source of more involved modules, where each export or local (proc) gets $include'd from a master .mpl text source file. By using the `read` command on the parent .mpl file I can access the material from within both commandline and Standard graphical Maple interfaces.

And currentdir and kernelopts(includepath) can be set programmatically, to give the whole process even more polish.

I don't care for the new RunWorksheet command as it can break some of the very useful evaluation rules that actual procedures have. (See here, for a simple example of said benefits.) It's not conducive to writing procedures. And it's awkward to set up. And then there is debugging it...

One bit difference between using plaintext & read versus libname & .mla Library archives is that the former may need to do more work if the source file actually does some computation or processing work. If the source file sets up a really big module package, or does other pre-calculation, then one might not want that to be reproduced with every re-read of the source.

acer

I set up the 2008 version of MSVC++ on a 64bit Windows 7 Pro machine, and Maple 14's Standard GUI and its Compiler work for me. More importantly, enabling the Compiler did not break the Standard GUI for me.

I installed the Visual Studio components after installing Maple 14. And then I ran Compiler:-Setup.

I do see this file, after installing the Visual Studio components.

 C://Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin/vcvars64.bat

First things first. Did you install (MVSC++ download of) the Visual Studio Express Edition (2008 version)?

Next, did you also install the Windows SDK for Windows Server 2008 and .NET Framework 3.5? My understanding is that the vcvars64.bat file is included in that SDK.

ps. I have heard a rumour that someone got the 2010 Visual Studio Express Edition to work, but only after (even more) fiddling (and possibly even writing by hand) to get that batch file. I haven't done it, at this date.

pps. Did you know that you can configure the Standard GUI to use Worksheets (not Documents) with 1D Maple Notation (not 2D Math input) by default in new sessions? That means you can get new features like polar axis plotting, 2D Math in plot captions, etc, etc, in inlined (not just Maplet) plots, while retaining quite a bit of the look & feel of the Classic GUI's "red prompt".

acer

You should be able to handle this in one of two ways. You can either test that the result is of a type (that a solution would take), or you can test whether the result is NULL or an unevaluated `fsolve` call.

result := fsolve(...);

if result = NULL or type(result, 'specfunc(anything,fsolve)' then
  no_solution_found := true;
end if;

# or, in the multivariate case,

if not type(result, set(symbol=complex(numeric))) then
  no_solution_found := true;
end if;

Notice that if you are choosing to test whether the result has a given form then the type-check may depend on how you called fsolve. These next two should illustrate that. Note also that you can choose to test whether the numeric result is purely real (ie. of type numeric which would be purely real instead of type complex(numeric) which might have nonzero imaginary part).

> result := fsolve( sin(5*x+3) , {x});
                      {x = 0.02831853072}

> type(result,set(symbol=numeric));
                              true

> result := fsolve( sin(5*x+3) , x);
                         0.02831853072

> type(result,numeric);
                              true

One can see, that it's a bit easier to check whether the `fsolve` attempt failed. If you had success, then how you pick apart the result will depend on how you called fsolve, and perhaps on how many variables were involved or whether the input was a univariate polynomial (in which case multiple solutions may be returned). How you test for that, or how you pick apart the solution, will thus depend on the problem at hand.

Now here is a related digression. You have realized that the result maybe a so-call unevaluated fsolve call, which is a fancy way of describing the situation that fsolve returns something that looks like the original call -- ie. a function call to `fsolve` itself.

If you test this at the top-level, outside of a procedure, then Maple will try once again to evaluate that function call when you inspect it by passing it on to your test. You likely don't want that, since you don't want your code to waste time duplicating a non-fruitful computation.

But if you instead perform the original fsolve call and the subsequent check inside a procedure, where result is a declared local variable, then any unevaluated fsolve function call will not get re-evaluated when your pass it around for the test.

Let's verify that claim, by simply counting how many times the argument to fsolve itself gets called. We'll use a procedure `f` as the thing to be solved-for, but the overall effect is the same even if the thing to be solved-for is an expression.

> restart:

> f:=proc(x)
>   global count;
>   count := count+1;
>   sin(5*x+3)-4;
> end proc:

# First let's do it inside a procedure.
 
> p:=proc(F) > global count; > local result; > result := fsolve(F); > printf("total number of f calls done: %a", count); > if type(result,numeric) then > print("root found"); > else > print("no root found"); > end if; > printf("total number of f calls done: %a", count); > end proc: > count := 0: > p(f); total number of f calls done: 828 "no root found" total number of f calls done: 828

Notice how the total number of calls to `f` did not increase due to calling `type` against the result

# Now, let's do it at the top-level, outiside if any procedure.

> count := 0: > result := fsolve(f); result := fsolve(f) > printf("total number of f calls done: %a", count); total number of f calls done: 828 > if type(result,numeric) then > print("root found"); > else > print("no root found"); > end if; "no root found" > printf("total number of f calls done: %a", count); total number of f calls done: 1656

Look what's happened. The total count of calls to `f` has doubled, following the `type` check!

The very act of passing the unevaluated fsolve call (assigned to `result`) to `type`() at the top-level causes it to get re-evaluated and thereby duplicates the entire unproductive attempt. But inside the procedure `p`, the variable `result` is a local variable and as such gets only one-level evaluation when passed into `type`(), and so does not cause a re-computation attempt.

When done at the top-level, in the case that the computation failed and returned unevaluated, the mere act of checking it causes the failing computation to be needlessly redone. This can be quite an important distinction when one is concerned with efficiency or when the computation takes a very long time. The very same issue would arise when calling `int` to do symbolic integrals and then passing around an unevaluated `int` call, except that `int` may be safe from this effect due to its having remember tables to store prior results. But the issue can arise elsewhere, since not all Library routines which can return unevaluated have remember tables.

This is one important reason why programming in Maple (ie. writing and using procedures) is important.

acer

Or you could try the top-level `copy` command.

acer

It looks like MTM:-subs doesn't really support multiple substitutions. This seems to be the case for both sequential substitutions (more that two arguments with all last denoting substitutions), or concurrent substitutions (first argument being a set).

If you want your `with` calls to be at the top then you can use the global form :-subs() in the code portion.

Or get rid of the with(MTM) if you don't need it, as was mentioned by Kamel.

In essence, MTM:-subs is designed to behave like the Matlab command subs and not like the Maple command `subs`. They were written for different products, and they behave differently. (It's not relevent that the Matlab `subs` command is part of it's old symbolic toolbox which used Maple once upon a time. The command was still designed for Matlab use and the Mathworks made it do what they wanted and had no cause to mimic Maple's `subs` command.)

acer

First 283 284 285 286 287 288 289 Last Page 285 of 336