acer

32587 Reputation

29 Badges

20 years, 36 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

I have a suspicion that this is a consequence of normal (as called by simplify) using the sign of the rational polynomial according to the lexicographic ordering of the variables.

Contrast these two cases, where variables are r and b versus r and s.

restart;
sign( (1-b/r)^(-1) );
                       -1

normal( sqrt((1-b/r)^(-1)) );
                    /    r   \1/2
                    |- ------|
                    \  -r + b/

restart;
sign( (1-s/r)^(-1) );
                        1

normal( sqrt((1-s/r)^(-1)) );
                     /  r  \1/2
                     |-----|
                     \r - s/

But, even if that speculation if correct, I'm not aware of a way to instruct kernel builtin normal to use a specific ordering for ascertaining the sign (or to enforce it somehow).

Which leaves "fixing up" the result, as recourse. One possibility here is:

H := u->simplify(sign(u)*numer(u))
        /simplify(sign(u)*denom(u)):

foo := sqrt((1-b/r)^(-1));

                      /   1   \1/2
               foo := |-------|
                      \1 - b/r/

evalindets(foo,ratpoly,H);

                       /  r  \1/2
                       |-----|
                       \r - b/

# or,

HH := u->simplify(sign(numer(u))*numer(u))
        /simplify(sign(numer(u))*denom(u)):

evalindets(foo,ratpoly,HH);

                       /  r  \1/2
                       |-----|
                       \r - b/

 

These aren't nearly as neat and quick as Axel's suggestion to turn the MeijerG call into a Sum.

kernelopts(version);

`Maple 2018.0, X86 64 LINUX, Mar 9 2018, Build ID 1298750`

(1)

restart;

ig:=(-5*ln(x)^4*Pi^4-20*ln(x)^2*Pi^4-8*Pi^4+120
    *MeijerG([[0, 0], [1, 1, 1]], [[0, 0, 0, 0, 0], []], x^Pi))
    /(120*Pi^4*(-1+x)^2):

fig := proc(X) option remember, system;
         if not X::numeric then return 'procname'(args); end if;
         NumericEventHandler(division_by_zero=default):
         evalf(eval(ig,x=X));
       end proc:

H:=IntegrationTools:-Expand(Int( (Re+I*Im)(fig(x)), x=4/10 .. 6/10,
                                 method=_d01ajc )):

CodeTools:-Usage( evalf(H) );

memory used=3.09GiB, alloc change=142.57MiB, cpu time=19.63s, real time=17.75s, gc time=3.46s

 

-0.5551687694e-2+0.8100967140e-40*I

(2)

restart;

ig:=(-5*ln(x)^4*Pi^4-20*ln(x)^2*Pi^4-8*Pi^4+120
    *MeijerG([[0, 0], [1, 1, 1]], [[0, 0, 0, 0, 0], []], x^Pi))
    /(120*Pi^4*(-1+x)^2):

fig := proc(X) option remember, system;
         if not X::numeric then return 'procname'(args); end if;
         NumericEventHandler(division_by_zero=default):
         evalf(eval(ig,x=X));
       end proc:

CodeTools:-Usage( evalf(Int( fig(x), x=4/10 .. 6/10, method=_Gquad )) );

memory used=1.39GiB, alloc change=142.57MiB, cpu time=8.97s, real time=8.16s, gc time=1.47s

 

-0.5551687694e-2+0.4526240059e-31*I

(3)

 

Download MI_int.mw

You don't need to introduce a second plot, in order to utilize plots:-display.

restart;

ode:= diff(y(x),x)=2*x:

p1:=DEtools:-DEplot(ode,y(x),x = -2 .. 2,y = -2 .. 2, [[0.1,0]],
               labels=["",""],
               linecolour = red, thickness=1,
               color = "#00ccff",
               'arrows' = 'medium'                    
               ):

plots:-display(p1, axis=[tickmarks=[color=red]],
               font=["Lucida Sans",bold,12]);

If you really are seeing a colored axis on your machine with the above code, then it's still possible to get the effect using custom tickmarks and Typesetting to color them.

The solve command is not supposed to emit an error. Your example is a bug. I will submit a bug report.

From the help page ?solve,details ,

  "If the solve command does not find any solutions, then it returns the empty
   sequence (NULL) (instead of an expression sequence or sets) or empty list
   (instead of a list of lists). This means that there are no solutions or the solve
   command cannot find the solutions."

and,

  "If the solve command cannot confirm that the solution set returned is complete,
   it sets the global variable _SolutionsMayBeLost to true and issues a warning."

So, no, it's not supposed to use an error to denote failure to find a solution. Nor is it supposed to return unevaluated.

I have reported quite a few similar bugs. There is some lack of defensive programming in the dispatch mechanism.

FWIW, turning the abs into (a multiplication by) signum can sometimes help, eg,

restart;
r:=evalc(Im(1/ln(x))):
solve(convert(r,signum),{x});
                            {0 < x}

And sure, you are free to wrap your solve calls in try..catch . In doing so you could even turn the error message into a WARNING. and/or set your own flag. Ie,

restart;

r:=evalc(Im(1/ln(x))):

solve(convert(r,signum),{x});

{0 < x}

(1)

solve_wrap:=proc()
  global SolveErrorFlag;
  try
    SolveErrorFlag:=false;
    solve(args);
  catch:
    SolveErrorFlag:=true;
    WARNING(cat(sprintf("%a : ",lastexception[1]),
                StringTools:-FormatMessage(lastexception[2..-1])));
  end try;
end proc:

solve_wrap( r, {x} );

Warning, SolveTools:-Inequality:-LinearUnivariateSystem : invalid input: member received FAIL, which is not valid for its 2nd argument, s

 

SolveErrorFlag;

true

(2)

solve_wrap( convert(r,signum), {x} );

{0 < x}

(3)

SolveErrorFlag;

false

(4)

 

 


Download solve_wrap.mw

restart;
                
A:=Matrix([[1,2,3,4],[5,6,7,8]]);
X:=Vector(4,symbol=x);
B:=Vector([10,10]);

# general solution
G:=LinearAlgebra:-LinearSolve(A,B);

# free parameters in G
params:=indets(G,name);

# generate ten of them
sols:={seq(eval(G,[params[1]=0,params[2]=i]),i=0..9)};

# check them
seq(LinearAlgebra:-Norm(A.s-B), s=sols);
simplify( exp(LambertW(1, Z)) - Z/LambertW(1, Z) ); # ok
                               0

simplify( exp(LambertW(1, Z)/2) - sqrt(Z/LambertW(1, Z)) ); # oops
                               0

The kernel can only respect the timelimit when it polls the elapsed time and the internal state is safe to return from.

Both of those things can only occur at discrete intervals. The granularity affects overall performance. But the internal state issue can, almost of necessity, sometimes be very coarse. There are kernel builtins which have to finish.

Sometimes clear examples can lead to tweaking of the mechanism, in my experience.

Have you tried to find the successive statements on your code where the timelimit is overrun, but not interrupted?

If you Matrix equation has the form A.x=b (where A is a Matrix and b is a Vector) then see the LinearAlgebra:-GenerateEquations command.

Otherwise, show us the form of the Matrix equation.

One of the calls to writeto is inside GTS2Usage and the other is at the top-level.

So you are redirecting to MyFile, and then not reverting to terminal (unless you successfully call GTS2Usage, which I don't see anywhere in the sheet). That's probably why you're not seeing the later output in the sheet.

Perhaps you intended something like the following, instead. Note that the finally clause is there so that, regardless of whether an error occurs, the writeto(terminal) will execute.

GTS2Usage := proc(H, F, Na, Nd)
  try
    MyFile := "C:/Users/Moshe/Desktop/Usage";
    writeto(MyFile)
    CodeTools:-Usage(GTS2(H, F, Na, Nd));
  catch:
    error;
  finally
    writeto(terminal);
  end try;
end proc;

The try..catch can trap most errors, but not infinite recursion (just so you are aware).

Also, even though you haven't yet shown how you plan to use GTS2timer yet, that proc looks suspect. It only returns the time() difference, and the results from GTS2 would be discarded. And GTS2 returns its results and doesn't act in-place on anything. Perhaps you intended it more like this:

GTS2timer := proc(H, F, Na, Nd)
  local res, st;
  st := time();
  res := GTS2(H, F, Na, Nd);
  print( out = time()-st );
  return res;
end proc;

Do you really need individual timings for each GTS2 call? Are you trying to figure out why it sometimes consumes much resources for specific inputs, or are you also interested in how its internals are consuming resources for general inputs? I'm just wondering whether profiling GTS2 might also be of interest to you.

Note that the value of your Fcn1 is not sqrt(a), because the call to sqrt has evaluated.

Fcn1 := sqrt(a):

lprint(Fcn1);
  a^(1/2)

You can delay evaluation when assigning to Fcn1, and then pass to codegen[cost] with only 1-level evaluation of its argument.

restart;              
Fcn1 := 'sqrt(a)';

                  Fcn1 := sqrt(a)

codegen[cost]( eval(Fcn1, 1) );

                     functions

Fcn2 := 'sin(sqrt(a))';

                Fcn2 := sin(sqrt(a))

codegen[cost]( eval(Fcn2, 1) );

                    2 functions

But this approach may not help much if the expressions your trying to measure are the result of some computation. Another approach might be be to have your computations done by procedure(s), and then measure their cost(s). Eg,

restart;
f := proc() sin(sqrt(a)); end proc;

        f := proc() sin(sqrt(a)) end proc

codegen[cost]( f );
                  2 functions

It's difficult to suggest an approach without knowing more about where your target expressions come from. Are they the result of a separate computation? Or is it their computation/production that you are trying to measure?

As a side note (possibly not relevant to you), even using a procedure will not prevent automatic simplification, since that also occurs during the interal re-writing of the statement sequences in the procedure body. (A more modern implementation might make use of ToInert, but that's another story.) For example,

restart;

'2*(x+y)';  # automatic simplification cannot be prevented by uneval quotes

                      2 x + 2 y

codegen[cost]( '2*(x+y)' );

            additions + 2 multiplications

codegen[cost]( proc() 2*(x+y); end proc );

            additions + 2 multiplications

# internally, this happened
`intrep/makeintrep`( proc() 2*(x+y); end proc );

     Proc(Name(nam .. float), Parameters(), Options(),
          Description(), Locals(), Globals(),
          StatSeq(2 x + 2 y))

Here are two ways to create it.

You could create either row Vectors or column Vectors, depending on which you want.

Vector[row]([seq(0..20,0.5)]);

# trunc((20-0)/(0.5)+1)  is just 41

Vector[row]( trunc((20-0)/(0.5)+1) ,(i)->(i-1)*0.5);

Apart from suppressing the ellipses altogether (as Thu has shown), there is also the possibility of stretching the ellipse or reducing the font size.

Your question mentioned the possibility to "modify the ellipses", but without "ad hoc modifications". Surely that only makes sense if you provide at least some guideline of what would be an acceptable modification. For example, do you mean that you would only want the ellipse re-jigged to the longest label if it could be done fully automatically and robustly?

I'll toss these out there, in case another reader is interested but with less restrictions about ad hoc changes.

restart;
with(GraphTheory):
g := Graph({{"azertyuiopqsdfghjklmwxcvbn", 1}, {"azertyuiopqsdfghjklmwxcvbn", 2}}):
P := DrawGraph(g, style=tree, root="azertyuiopqsdfghjklmwxcvbn"):
P;
subsindets(P,specfunc(FONT),u->FONT("HELVETICA","DEFAULT",8));
plots:-display(P,size=[1000,1/2]);

Matrix indexing starts from 1.  But Array indexing can start from 0 (or whatever you want).

And you can create an rtable-Alias of a Matrix that behaves like an Array and which starts its indexing from 0.

Since it is an Alias, changes to either of them also appear in the other. They act like views onto the same data in memory.

So you can use indexing-from-zero to assign to (or access from) the Array's name, but the values will come from the Matrix. And vice-versa.

restart;

X := LinearAlgebra:-RandomMatrix(3);

Matrix(3, 3, {(1, 1) = 27, (1, 2) = 99, (1, 3) = 92, (2, 1) = 8, (2, 2) = 29, (2, 3) = -31, (3, 1) = 69, (3, 2) = 44, (3, 3) = 67})

(1)

XA := ArrayTools:-Alias(X, [0..2,0..2]):

X[1,1];

27

(2)

XA[0,0];

27

(3)

XA[0,0] := 17;

17

(4)

X[1,1];

17

(5)

X . X;  # usual Matrix-Matrix multiplication

Matrix(3, 3, {(1, 1) = 7429, (1, 2) = 8602, (1, 3) = 4659, (2, 1) = -1771, (2, 2) = 269, (2, 3) = -2240, (3, 1) = 6148, (3, 2) = 11055, (3, 3) = 9473})

(6)

XA . XA:  # elementwise multiplication
Matrix(%);

Matrix(3, 3, {(1, 1) = 289, (1, 2) = 9801, (1, 3) = 8464, (2, 1) = 64, (2, 2) = 841, (2, 3) = 961, (3, 1) = 4761, (3, 2) = 1936, (3, 3) = 4489})

(7)

 

Download MatrixArrayAlias.mw

 

Did you try,

interface(prettyprint=1):

in your cmaple session?

That is the default for the Command Line Interface (CLI).

Executing the code which defines a procedure is not the same as calling that procedure.

You have done the former, but not the latter.

More specifically, applying eval to a procedure does not call the procedure.

To actually call the procedure use round brackets. That applies it (even if there are no arguments within the brackets).

So, if

Glyph2:-GetSpace('default')

returned a procedure then the following would also immediately call that returned procedure (ie. apply it to zero arguments, or invoke it).

Glyph2:-GetSpace('default')()

In your actual module example I don't see the point of wrapping some procedure definitions in uneval quotes (single right quotes).

First 177 178 179 180 181 182 183 Last Page 179 of 338