acer

32333 Reputation

29 Badges

19 years, 320 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

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.

Your example,
  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
   - evalc, radnormal, evala, normal

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.

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);

`Maple 2020.1, X86 64 LINUX, Jun 8 2020, Build ID 1474533`

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]);

 

Download ColumnGraph_Problem_ac.mw

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"
where userid is your Windows id. (See also kernelopts(':-homedir') output, if relevant.)

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).

[edit] 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[8]):
RV          := RandomVariable(Binomial(n_trials,pat)):

subscribers := CodeTools:-Usage( map(proc(u) option hfloat;
                                       global pat;
                                       pat := u;
                                       Sample(RV,dummyV);
                                       dummyV[1];
                                     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);

 

Download subscribers_ac1.mw

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);

arccos(1/3)

1.230959417

70.52877935

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);

[1/3, 1/3, -1/3]

[-1, -1, 1]

[1, 0, 0]

with(LinearAlgebra):

arccos( <cM-cF>^%T . <cM-cQ> / (Norm(<cM-cF>,2)*Norm(<cM-cQ>,2)) );

arccos(1/3)

# 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)) );

arccos(1/3)

 

Download regtetra_dihedral.mw

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);

%binomial(20, 10)*p^10*(1-p)^10

foo;

%binomial(20, 10)*p^10*(1-p)^10

value(foo);

184756*p^10*(1-p)^10

# If you do not prefer the gray round brackets

InertForm:-Display(foo, ':-inert'=false);

%binomial(20, 10)*p^10*(1-p)^10

# optionally

`print/%binomial`:=proc() ':-C'(args); end proc:

 

foo;

%binomial(20, 10)*p^10*(1-p)^10

value(foo);

184756*p^10*(1-p)^10

`print/%binomial`:=proc(m,n) ':-C'[n]^m; end proc:

 

foo;

%binomial(20, 10)*p^10*(1-p)^10

value(foo);

184756*p^10*(1-p)^10

# 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;

%binomial(20, 10)*p^10*(1-p)^10

value(foo);

184756*p^10*(1-p)^10

`print/%binomial`:=proc(m,n)
    uses Typesetting;
    mscripts(mi("C"),mn(convert(n,string)),
             none()$3,mn(convert(m,string)),none());
end proc:

 

foo;

%binomial(20, 10)*p^10*(1-p)^10

value(foo);

184756*p^10*(1-p)^10

# 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;

%binomial(20, 10)*p^10*(1-p)^10

value(foo);

184756*p^10*(1-p)^10

NULL

Download inertbinomial.mw

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))]));
instead of,
   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.

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

zip(f,A,B);

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

Try,

  getenv("MAPLE");

instead of your attempt,

  getenv("$MAPLE"); 

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

 

Here is a way, for Maple 2015.

restart;

kernelopts(version);

`Maple 2015.2, X86 64 LINUX, Dec 20 2015, Build ID 1097895`

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);

-0.1867377355e-42*y+0.453450449e-42+int(-0.4558450000e-42*q^4*y*ln(1.+(q^2+2.)^(1/2)), q = 0 .. 1)+int(-0.4558450000e-42*y*ln(1.+(q^2+2.)^(1/2))*q^2, q = 0 .. 1)

factor(expand(%));

-0.4211444464e-42*y+0.453450449e-42

#
# 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(%));

0.1464659791e-41*q^2-0.1568649000e-41*q^2*y+0.2813991838e-42*q^3*y

 

Download question_integration_ac.mw

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.

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

Your call removes entries whose value equals the value of A[1], which is 1. Both the entries A[1] and A[3] satisfy that criterion of having the same value as A[1], and consequently both are removed.

If you simply want to chop off only the first entry then it's more efficient to do it via indexing, eg.
  A:=Array([1,4,1,7]);
  A[2..-1];  # without reindexing from 1
  rtable_redim(A[2..-1],1..op([2,2],A)-1); # with reindexing from 1

(If you care about reindexing a great deal then it could be easier to use a Vector instead of an Array.)

But you haven't indicated clearly what your actual purpose is, so it's tricky to guess what might be best.

 

I am not sure what you are shooting for. Is it an expression that you could manipulate symbolically, or a fast procedure to evaluate at numeric values, or...?

You can use a symbol j (in lieu of 6) if you utilize binomial, and obtain various forms. I don't really see why hypergeom would serve much better than inert Sum, primarily because you didn't tell us anything about how you plan to use your result. I don't really understand what kind of formula or general expression you might be hoping for.

Or you could use a procedure taking j (or j and w) as arguments.

restart;

Sg:=(n,w)->1-(1-w)^n*add(binomial(n-1+i,n-1)*w^i,i=0..n-1):
Sg(6,3);

-4682367

Sg(6,w);
eval(%,w=3);

1-(1-w)^6*(252*w^5+126*w^4+56*w^3+21*w^2+6*w+1)

-4682367

S:=sum(w*binomial(j+i,i+1)*w^(j-1)*(1-w)^(i+1),i=-1..j-2);

1-w*binomial(2*j-1, j)*w^(j-1)*(1-w)^j*hypergeom([1, 2*j], [j+1], 1-w)

S6:=convert(eval(S,j=6),elementary);

1-(1-w)^6*(252*w^5+126*w^4+56*w^3+21*w^2+6*w+1)

eval(S6,w=3);

-4682367

add(w*binomial(6+i,i+1)*w^(6-1)*(1-w)^(i+1),i=-1..6-2);

w^6+6*w^6*(1-w)+21*w^6*(1-w)^2+56*w^6*(1-w)^3+126*w^6*(1-w)^4+252*w^6*(1-w)^5

eval(%,w=3);

-4682367

add(eval(w*binomial(6+i,i+1)*w^(6-1)*(1-w)^(i+1),w=3),i=-1..6-2);

-4682367

A:=simplify(1-(1-w)^j*sum(binomial(j-1+i,j-1)*w^i,i=0..j-1));
convert(eval(A,[j=6,w=3]),elementary);
convert(eval(A,[j=6]),elementary);
eval(%,w=3);

binomial(2*j-1, j-1)*w^j*hypergeom([1, 2*j], [j+1], w)*(1-w)^j

-4682367

-w^6*(252*w^5-1386*w^4+3080*w^3-3465*w^2+1980*w-462)*(1-w)^6/(-1+w)^6

-4682367

 

Download addbinomial.mw

[edit] The OP has not said much about how this is to be used. There is at least one other interesting case -- where an expression denoting the case that j is unspecified has to be passed around, but which is supposed to compute to a numeric result when the parameter is subsequently substituted by a number. Using uneval-quotes around a function call can be tricky and fragile, and passing around such a beast can be irksome.

So another possible useful case is the procedure which returns unevaluated unless some arguments are numeric. For example, below the calls Sg(j,w) or Sj(j,3) can be passed around without worry of prematurely invoking add with wrong arguments -- until such time as j gets a numeric value. Modify as needed.

restart;

Sg:=proc(n,w)
      if not n::numeric then return 'procname'(args); end if;
      1-(1-w)^n*add(binomial(n-1+i,n-1)*w^i,i=0..n-1);
end proc:

Sg(6,3);

-4682367

Sg(j,3); # no error emitted
eval(%,[j=6]);

Sg(j, 3)

-4682367

# And, now, for example...
#plot([Sg(2,w),Sg(3,w)], w=0..1);

 

Download addbinomial2.mw

First 114 115 116 117 118 119 120 Last Page 116 of 336