## 19562 Reputation

14 years, 317 days

## evalb and is...

Be careful about terminology. You wrote, "I think, `evalb` is used to compare numbers and `is` used to compare expression, logic. Is this true?" That sentence is not precise, in Maple terminology, and that can lead to misunderstanding here.

Think instead in terms of technical Maple terminology, for example whether something is of type numeric. That includes floating-point numbers, integers, and fractions (rationals, with integers in numerator and denominator). That does not include exact representations such as sqrt(2). Yes, that denotes a "number" in the common mathematical sense, but it is not of type numeric to Maple. A related and useful class is things of type realcons, which would produce something of type numeric if evalf were applied.

The evalb command can compare equality and inequality relations of items that are both of type numeric. It can also test whether two structues are identically the same, by which I mean that they have the same address in memory.

So you cannot generally, reliably compare two expressions (of type algebraic but not numeric) with the evalb command unless you can put both into a canonical form, in which case they are uniquified and the canonical forms are identically the same.

f := x + 1 = (x^2 - 1)/(x - 1);
can be simplified (using simplify or normal, for example) so that lhs and rhs of that normal form are in fact the very same expression. That is why evalb(simplify(f)) returns true.

But not all expressions can be easily put by Maple into some canonical form. (For example, there are mathematically equivalent formulations for some expressions involving trig and special function calls for which a choice of canonical reformulation is not obvious.) That's one advantage of using is, as it has a variety of mathematical operations it can do for comparison.

Another significant advantage of the is command is that it can (often) utilize assumptions on names in symbolic expressions.

Here are some tips:

1) For mathematical testing of an equation (ie. A=B), it can sometimes help is by querying is(A-B=0) since (while zero-testing is hard) at least the target form is clear: zero.

2) In general the is command performs more strongly that simplify (or its friends, normal, radnormal, shake, evalc, rationalize, combine, and expand) alone. It is rare that it helps to make a call such as is(simplify(A-B)=0) , but examples do exist.

3) For inequality testing involving expressions of type realcons you may generally be better off invoking the is command, rather than applying evalf and risking a mistake due to close roundoff error. Like most "rules", this too has its exceptions.

4) If you are going to use the is comand then you might have to write your code so that it handles the case that is returns FAIL instead of true or false.

5) For verification of floating-point results from a computation against a target value you might look at the testfloat command, or the verify command with a float comparator.

6) For verification of data structures (lists, sets, Vectors, etc) you could also look at a call of the verify command, according to the type of the structures' members.

It's a large topic, and a textbook on Maple could be written while covering it comprehensively.

Background reading, Help pages for Topics:
-  testfloat
- verify
- evalrshake
- testeq
- signum
- type numeric, realcons, algebraic

The catch clause is intended to catch whatever throws a catchable error with the given prefix1, and there could be more than one statement in the try clause that emits such.

One point of the finally clause is that its code is supposed to run if either an error is caught or no error occurs. If you don't want some code run when a error is caught then put it later in the try clause, instead -- eg. after your conditional.

In complicated scenarios you may find it helpful to set and use one or more flags, or to use a nested try..catch, etc.

Does the error message upon time-out always begin with "time expired"?

1 Managing uncatchable errors is a different story.

## workaround...

You can write your own wrapper around ColumnGraph, allowing you to retain your plots:-setoptions setting in your initialization file. You can make it ignore or respect the setting, and override it.

(A bug report will be submitted...)

 > restart;
 > kernelopts(version); > plots:-setoptions(size=[250,250]);
 > with(Statistics):
 > # # This version ignores setoptions choice for size, # but allows you to force it. # SColumnGraph:=proc()   uses plots; local oldsize, P;   oldsize:=setoptions(':-size'):   setoptions(':-size'=[':-default',':-default']);   try     P:=Statistics:-ColumnGraph(_passed);   catch "":     error;   finally     setoptions(':-size'=oldsize);   end try;   return P; end proc:
 > T := [StringTools[CharacterFrequencies]("antidisestablishmentarianism")]:
 > SColumnGraph(T); > SColumnGraph(T, 'size'=plots:-setoptions(':-size')); > SColumnGraph(T, 'size'=[300,150]); > # # This version respects setoptions choice for size, # but allows you to disregard it. # RColumnGraph:=proc()   uses plots; local oldsize, P, S;   oldsize:=setoptions(':-size'):   setoptions(':-size'=[':-default',':-default']);   try     S:=select(type,[_passed],identical(size)=anything);     S:=`if`(nops(S)>0,S[-1],':-size'=oldsize);     P:=Statistics:-ColumnGraph(_passed,S);   catch "":     error;   finally     setoptions(':-size'=oldsize);   end try;   return P; end proc:
 > T := [StringTools[CharacterFrequencies]("antidisestablishmentarianism")]:
 > RColumnGraph(T); > RColumnGraph(T, 'size'=[':-default',':-default']); > RColumnGraph(T, 'size'=[300,150]); >

## personal initialization file...

Could you not also try using a personal Maple initialization file, so that you wouldn't have to change its contents when you upgrade your Maple release?

That is to say, from the initialization Help page,
"C:\Users\userid\maple.ini"

## comment...

Let me know if I did this incorrectly. This is not thread-safe (but I suspect that you could make a variant that is -- each thread getting its own parameter name and dummy container Vector).

 I see that mmcdara has written about subscribers being a discrete uniform random variable over {0, ..., 16}, and getting the fast direct generation of the sample. But I won't delete this, since it might interest someone later, to compare varying the parameter value of a preformed RV against generating a sample from a fresh call to Binomial (or other distribution flavour) for each entry.

 > restart:
 > randomize():
 > with(Statistics):
 > n_draw      := 10000: prior_rate  := Sample(Uniform(0, 1), n_draw): n_trials    := 16: dummyV      := Vector(1,datatype=float): RV          := RandomVariable(Binomial(n_trials,pat)):
 > subscribers := CodeTools:-Usage( map(proc(u) option hfloat;                                        global pat;                                        pat := u;                                        Sample(RV,dummyV);                                        dummyV;                                      end proc,                                      prior_rate) ):

memory used=110.80MiB, alloc change=33.00MiB, cpu time=753.00ms, real time=754.00ms, gc time=48.49ms

 > Histogram(subscribers, discrete=true, view=[-1..n_trials+1, default], thickness=10); >

## a couple of ways...

You could compute it using the geom3d package, either by command or from coordinates (after a projection). Or you can compute it with LinearAlgebra. See below.

If you wanted you could add labels to the points (vertices, midpoint, and projection to the plane).

 > restart;
 > with(geom3d):
 > point(A,1,1,1), point(B,1,-1,-1), point(C,-1,1,-1), point(F,-1,-1,1):
 > gtetrahedron(T,[A,B,C,F]):
 > plane(P1,[A,B,C]), plane(P2,[A,B,F]):
 > FindAngle(P1,P2); evalf(%); evalf(%*180/Pi);   > projection(Q, F, P1):  # Q is the projection of F onto plane P1 midpoint(M, A, B):     # M is the midpoint between A and B
 > triangle(Tr1,[A,B,C]), triangle(Tr2,[A,B,F]): segment(L_FQ,[F,Q]), segment(L_MQ,[M,Q]), segment(L_MF,[M,F]):
 > plots:-display(draw(Tr1,color="Orange"),draw(Tr2,color="Orange"),                draw(T,transparency=0.9,color=gray),                draw(Q,symbolsize=20,symbol=solidsphere),                draw(F,symbolsize=20,symbol=solidsphere),                draw(M,symbolsize=20,symbol=solidsphere),                draw(L_FQ,linestyle=dash,thickness=3),                draw(L_MQ,linestyle=dot,thickness=3),                draw(L_MF,linestyle=dot,thickness=3),                orientation=[5,-15,-20], size=[500,500],                view=[-1..1,-1..1,-1..1], axes=box); > # Alternatively, compute it from the coordinates # of F, Q, and M cQ:=coordinates(Q); cF:=coordinates(F); cM:=coordinates(M);   > with(LinearAlgebra):
 > arccos( ^%T . / (Norm(,2)*Norm(,2)) ); > # Or, without geom3d vA:=<1,1,1>: vB:=<1,-1,-1>: vC:=<-1,1,-1>: vF:=<-1,-1,1>: X1:=CrossProduct(vA-vC, vA-vB): X2:=CrossProduct(vA-vF, vA-vB): arccos( X1 . X2 / (Norm(X1,2)*Norm(X2,2)) ); >

## inert...

Firstly, using a common bracketed notation for pretty-printing the result, and then some alternatives.

 > restart;
 > MySumP := (j::integer) ->   seq(%binomial((j+10),(i+10))*p^(j+i)*(1-p)^(j+i), i= 0..0):
 > foo := MySumP(10); > foo; > value(foo); > # If you do not prefer the gray round brackets InertForm:-Display(foo, ':-inert'=false); > # optionally `print/%binomial`:=proc() ':-C'(args); end proc:
 >
 > foo; > value(foo); > `print/%binomial`:=proc(m,n) ':-C'[n]^m; end proc:
 >
 > foo; > value(foo); > # Now with upright Roman "C" `print/%binomial`:=proc(m,n)     uses Typesetting;     msubsup(mtext("C"),mn(convert(n,string)),             mn(convert(m,string))); end proc:
 >
 > foo; > value(foo); > `print/%binomial`:=proc(m,n)     uses Typesetting;     mscripts(mi("C"),mn(convert(n,string)),              none()\$3,mn(convert(m,string)),none()); end proc:
 >
 > foo; > value(foo); > # Now with upright Roman "C", and smaller numerals `print/%binomial`:=proc(m,n)     uses Typesetting;     mscripts(mtext("C"),mn(convert(n,string),':-mathsize'=10),              none()\$3,mn(convert(m,string),':-mathsize'=10),none()); end proc:
 >
 > foo; > value(foo); > ## workaround...

If you don't want your PDF file interspersed with empty spaces due to forced page-breaks then you might also try using Array-plots for your 3D plots.

Eg,
plots:-display(Array([plot3d(sin(x))]));
plot3d(sin(x));

That will put a Table border around each such plots, though you can toggle off the visibility of its borders using right-click menu choice Table->Properties just before exporting.

## zip...

```A:=[1,2,3]:
B:=[7,8,9]:

zip(f,A,B);

[f(1, 7), f(2, 8), f(3, 9)]

```

## source mode...

I often adjust my Mapleprimes posts by switching the editor into "source" mode, using the icon at the top left of the editor.

In source mode, such gray fixed-width text areas can be delineated by the <pre> ... </pre> markup tags.

It works like the HTML tags of the same name.

## getenv...

Try,

getenv("MAPLE");

getenv("\$MAPLE");

Or see the examples on the ?getenv Help page, which do not include the dollar symbol.

## Maple 2015...

Here is a way, for Maple 2015.

 > restart;
 > kernelopts(version); > L := 1:
 > AAA := 3.888022*10^(-42)*p*q-4.75389*10^(-42)*y*p*q+7.4699*10^(-43)*y*p*q^2+9.1169*10^(-43)*y*p^2*q:
 > map(int,(int(q*AAA/sqrt(p^2+q^2+1),p=0..L)),q=0..L); > factor(expand(%)); > # # The following suggestion doesn't work in Maple 2015, since # IntegrationTools:-Expand incorrectly pulls q out of both integrals. #
 > restart;
 > L := 1:
 > AAA := 3.888022*10^(-42)*p*q-4.75389*10^(-42)*y*p*q+7.4699*10^(-43)*y*p*q^2+9.1169*10^(-43)*y*p^2*q:
 > Int(q*AAA/sqrt(p^2 + q^2 + 1), [p = 0 .. L, q = 0 .. L]):
 > evalf(IntegrationTools:-Expand(%)); >

## COLOR(NONE)...

After some investigation, it seems that the problem is due to the plotting substructure COLOR(NONE) that is in the encoded output for the odeplot call(s) in your worksheet saved in Maple 7.

In Maple 2015.2 and earlier that errant substructure seems to get ignored when the worksheet is reopened, but in Maple 2016 and later it causes the GUI's layout remndering to appear corrupted.

In Maple 16 through to Maple 2015, the errant substructure does not get stored in the encoded output in the re-saved XML .mw file.

I will submit a bug report, noting that:
- Encountering a problematic PLOT substructure shouldn't ruin the whole sheet's rendering. At worst the plot's output could be ignored and discarded upon the problematic reopening.
- Since Maple 7 allowed this to be created, and since versions up to Maple 2015 accomodated it fine, then later releases should also accomodate it upon re-opening  (and discard it).

I could write a script to that could fix up the problematic .mw file, and then open in a new GUI tab. But not until next week. The problem might even be isolated to the output returned by the odeplot command in the much older versions (I cannot check right now). It isn't a common issue.

## display...

The command plots:-display3d does nothing except pass on its arguments to the same internal procedure that plots:-display does.

You might as well use plots:-display in all cases where you'd want to use either, and not make things confusing to your students.

The only difference is minor, in that plots:-display utilizes a try..catch so that its errors are caught and rethrown (which can affect where they appear to come from).

```showstat(plots:-display3d);

plots:-display3d := proc()
1   `plots/display`(_passed)
end proc```
```showstat(plots:-display);

plots:-display := proc()
1   try
2       `plots/display`(_passed)
catch :
3       error
end try
end proc
```

By the way, your last example is just wrong. There is no display3DA command, which name you called. Your call to it may produce output as a pair of plots wrapped in an unevaluated function call to that same name, but that signifies nothing. You'd get a similar output if your called  foobar({p1,p2});  where foobar is just some unassigned name.

## alternatives...

Alternatively, in a single statement,

```restart;
expr := Sum((-1)^n - 1, n = 1 .. infinity):

simplify(subs(n=nn,op(1,expr))) assuming nn::even;

0```

I mention the above because it might help in a similar situation where the wrapping command is not simplify and doesn't provide for its own assume option.

I should probably also mention this mechanism.

```restart;
Physics:-Setup(assumingusesAssume = true):

expr := Sum((-1)^n - 1, n = 1 .. infinity):

simplify(op(1,expr)) assuming n::even;
0```

More tricky, ie. harder IMO to get right more generally,

```value(simplify('`%assuming`'([op(1,expr)],[n::even])));

0

value('`%assuming`'(['simplify'(op(1,expr))],[n::even]));

0```
﻿