Product Tips & Techniques

Tips and Tricks on how to get the most about Maple and MapleSim

Recently, @zenterix asked a question related to solving the quantum mechanics of the finite-wall-height particle-in-a-box problem. In the last two decades or so I've been teaching a quantum mechanics course every second year, in which I sketch the method of solution of this problem for the class, I but do not get into the mathematical details. A few times I've started to work on it in Maple, but abandoned it because of lack of time. So I decided to persist this time.

This post is more about some of the challenges and tradeoffs in making it work, hence the title. The title is also a nod to the fact that this problem appears in Engel's textbook [1] in a chapter entitled "Applying the particle in a box model to real-world topics". You don't need to know much about quantum mechanics to understand it. From the mathematical point of view you are solving three ordinary differential equations (in three regions) and stitching the solutions together so that the solution, a wavefunction, is continuous with continuous derivative and tends to zero at plus infinity and minus infinity.

The three regions and the wavefunctions for three eigenvalues (energies) are shown here in the figure, which is the final output of the worksheet. Next is the worksheet and I'll comment further on it below.

(It's a quirk of quantum mechanics that we plot two things with different units (wavefunctions and energy) on the same axis, and worse, we offset one by the other.)

Bound states for particle in finite height box of wall height
V(x) = piecewise(x < -(1/2)*a, V__0, -(1/2)*a <= x and x <= (1/2)*a, 0, (1/2)*a < x, V__0)
I'll call these regions left, box and right respectively.

restart

Schroedinger equation. Here as elsewhere "=0" is implied.

Schroedinger := -`&hbar;`^2*(diff(psi(x), x, x))/(2*m)+V*psi(x)-E*psi(x)

-(1/2)*`&hbar;`^2*(diff(diff(psi(x), x), x))/m+V*psi(x)-E*psi(x)

(1)

Nondimensionalize length as units of box length, X = x/a. Since psi(x)^2*dx is unitless probability, psi(x) has dimensions 1/length^(1/2)so we define a dimensionless Phi = a^(1/2)*psi

tr := {x = a*X, psi(x) = Phi(X)/sqrt(a)}; NDSchroedinger := PDETools:-dchange(tr, Schroedinger, [X, Phi(X)], params = [`&hbar;`, m, a], simplify)

{x = a*X, psi(x) = Phi(X)/a^(1/2)}

 

-((1/2)*`&hbar;`^2*(diff(diff(Phi(X), X), X))+a^2*m*Phi(X)*(E-V))/(a^(5/2)*m)

(2)

This will also change the normalization integrals, e.g., over the box region:

normint := Int(psi(x)^2, x = -(1/2)*a .. (1/2)*a); NDnormint := PDETools:-dchange(tr, normint, [X, Phi(X)], params = [`&hbar;`, m, a], simplify)

Int(psi(x)^2, x = -(1/2)*a .. (1/2)*a)

 

Int(Phi(X)^2, X = -1/2 .. 1/2)

(3)

Outside the box we have 0 <= E and E < V with V = V__0. Define a dimensionless positive constant kappa:

`&kappa;__eqn` := kappa = a*sqrt(2*m*(V__0-E)/`&hbar;`^2); de_outside := simplify(sqrt(a)*kappa^2*(eval(NDSchroedinger, {isolate(`&kappa;__eqn`, m), V = V__0}))/(E-V__0)); outside := rhs(dsolve(de_outside))

kappa = a*2^(1/2)*(m*(V__0-E)/`&hbar;`^2)^(1/2)

 

diff(diff(Phi(X), X), X)-kappa^2*Phi(X)

 

c__1*exp(-kappa*X)+c__2*exp(kappa*X)

(4)

Inside the box we have V = 0 and E > 0. Define a dimensionless positive constant k.

k__eqn := k = a*sqrt(2*m*E/`&hbar;`^2); de_box := simplify(-sqrt(a)*k^2*(eval(NDSchroedinger, {isolate(k__eqn, m), V = 0}))/E); box := rhs(eval(dsolve(de_box), {c__1 = A, c__2 = B}))

k = a*2^(1/2)*(m*E/`&hbar;`^2)^(1/2)

 

diff(diff(Phi(X), X), X)+k^2*Phi(X)

 

A*sin(k*X)+B*cos(k*X)

(5)

We have seven unknowns {A, B, E, c__1(L), c__1(R), c__2(L), c__2(R)}, where for example c__1(L) means Maple's c__1 for the left region. We need seven equations: goes to 0 at x = -infinityand at x = infinity(or Phi(X) wouldn't be square integrable), continuity at the two box boundaries, slopes continuous at the two box boundaries, and normalization. We deal with the ones at `&+-`(infinity)first.

At X = -infinity the wavefunction will be unbounded unless one of the constants goes to zero. We'll rename the other one A__L or A__R. The code here is just to handle the fact that c__1 and c__2 can be the the opposite way around, depending on the session.

`assuming`(['limit(outside, X = -infinity)' = limit(outside, X = -infinity)], [kappa > 0]); left0 := eval(outside, `~`[`=`](`minus`(indets(rhs(%), name), {infinity}), 0)); left1 := eval(left0, `~`[`=`](indets(left0, suffixed(c)), A__L)); `assuming`(['limit(outside, X = infinity)' = limit(outside, X = infinity)], [kappa > 0]); right0 := eval(outside, `~`[`=`](`minus`(indets(rhs(%), name), {infinity}), 0)); right1 := eval(right0, `~`[`=`](indets(right0, suffixed(c)), A__R))

limit(c__1*exp(-kappa*X)+c__2*exp(kappa*X), X = -infinity) = signum(c__1)*infinity

 

A__L*exp(kappa*X)

 

limit(c__1*exp(-kappa*X)+c__2*exp(kappa*X), X = infinity) = signum(c__2)*infinity

 

A__R*exp(-kappa*X)

(6)

Now we have five unknowns {A, A__L, A__R, B, E}. The strategy will be to eliminate A, A__L, A__R and then find the eigenvalues E. Then we will have expressions for all three regions containing the unknown B, which we will find by the normalization condition (The normalization condition fixes the scale of the wavefunction so that the probability of finding the particle somewhere is one.)

Continuity of the wavefunction and its derivative at the left boundary are below
We eliminate A__L and A using this boundary

bcleft := {eval(left1-box, X = -1/2), eval(diff(left1, X)-(diff(box, X)), X = -1/2)}; sol := solve(bcleft, {A, A__L}); left2 := eval(left1, sol); box2 := eval(box, sol)

{A__L*exp(-(1/2)*kappa)+A*sin((1/2)*k)-B*cos((1/2)*k), A__L*kappa*exp(-(1/2)*kappa)-A*k*cos((1/2)*k)-B*k*sin((1/2)*k)}

 

{A = -B*(sin((1/2)*k)*k-cos((1/2)*k)*kappa)/(sin((1/2)*k)*kappa+cos((1/2)*k)*k), A__L = B*k*(sin((1/2)*k)^2+cos((1/2)*k)^2)/(exp(-(1/2)*kappa)*(sin((1/2)*k)*kappa+cos((1/2)*k)*k))}

 

B*k*(sin((1/2)*k)^2+cos((1/2)*k)^2)*exp(kappa*X)/(exp(-(1/2)*kappa)*(sin((1/2)*k)*kappa+cos((1/2)*k)*k))

 

-B*(sin((1/2)*k)*k-cos((1/2)*k)*kappa)*sin(k*X)/(sin((1/2)*k)*kappa+cos((1/2)*k)*k)+B*cos(k*X)

(7)

Eliminate A__R at the right box boundary

bcright := {eval(box2-right1, X = 1/2), eval(diff(box2, X)-(diff(right1, X)), X = 1/2)}; elim := eliminate(bcright, A__R); right2 := eval(right1, elim[1]); energy_eqn := elim[2][]/B

{-B*(sin((1/2)*k)*k-cos((1/2)*k)*kappa)*sin((1/2)*k)/(sin((1/2)*k)*kappa+cos((1/2)*k)*k)+B*cos((1/2)*k)-A__R*exp(-(1/2)*kappa), -B*(sin((1/2)*k)*k-cos((1/2)*k)*kappa)*k*cos((1/2)*k)/(sin((1/2)*k)*kappa+cos((1/2)*k)*k)-B*k*sin((1/2)*k)+A__R*kappa*exp(-(1/2)*kappa)}

 

[{A__R = B*(2*sin((1/2)*k)*cos((1/2)*k)*kappa+2*cos((1/2)*k)^2*k-k)/(exp(-(1/2)*kappa)*(sin((1/2)*k)*kappa+cos((1/2)*k)*k))}, {-2*(sin((1/2)*k)*cos((1/2)*k)*k^2-sin((1/2)*k)*cos((1/2)*k)*kappa^2-2*cos((1/2)*k)^2*k*kappa+k*kappa)*B}]

 

B*(2*sin((1/2)*k)*cos((1/2)*k)*kappa+2*cos((1/2)*k)^2*k-k)*exp(-kappa*X)/(exp(-(1/2)*kappa)*(sin((1/2)*k)*kappa+cos((1/2)*k)*k))

 

-2*sin((1/2)*k)*cos((1/2)*k)*k^2+2*sin((1/2)*k)*cos((1/2)*k)*kappa^2+4*cos((1/2)*k)^2*k*kappa-2*k*kappa

(8)

Now we will get the quantized energies by finding which values will make energy_eqn zero. We recall the relationships of `&kappa;__` and k to energy:

k__eqn; `&kappa;__eqn;`

k = a*2^(1/2)*(m*E/`&hbar;`^2)^(1/2)

 

kappa = a*2^(1/2)*(m*(V__0-E)/`&hbar;`^2)^(1/2)

(9)

The energy scale is set by V__0, so can get a non-dimensionalized energy e = E/V__0 and a non-dimensional parameter b = a*sqrt(2*m*V__0/`&hbar;`^2).

b__eqn := b = a*sqrt(2*m*V__0/`&hbar;`^2); e__eqn := e = E/V__0; eqns := `assuming`([{simplify(eval(eval(k__eqn, isolate(e__eqn, E)), isolate(b__eqn, V__0))), simplify(eval(eval(`&kappa;__eqn`, isolate(e__eqn, E)), isolate(b__eqn, V__0)))}], [a > 0])

b = a*2^(1/2)*(m*V__0/`&hbar;`^2)^(1/2)

 

e = E/V__0

 

{k = (e*b^2)^(1/2), kappa = (-b^2*(e-1))^(1/2)}

(10)

So now for any values of the box length and height, one finds the parameter b describing the problem and solves for the possible e values.

energy_eqn2 := `assuming`([simplify((eval(energy_eqn, eqns))/b^2)], [b > 0, e > 0, e < 1])

2*e^(1/2)*(-e+1)^(1/2)*cos(b*e^(1/2))-2*e*sin(b*e^(1/2))+sin(b*e^(1/2))

(11)

Maple cannot find an analytical solution, so we will find the eigenvalues numerically. The zero solution is unphysical.

solve(energy_eqn2, e)

0, RootOf(-2*(-(_Z^2-b^2)/b^2)^(1/2)*(_Z^2/b^2)^(1/2)*b^2+2*tan(_Z)*_Z^2-tan(_Z)*b^2)^2/b^2

(12)

For any b, read off the possible energies off the vertical line for that b, e.g. there are 3 bound states for b = 9. For other values, choose bval and nsols on the next line appropriately.

bval := 9; nsols := 3; plots:-implicitplot([b = bval, energy_eqn2], b = 0 .. 15, e = 0 .. 1)

9

 

3

 

 

evals := [fsolve(eval(energy_eqn2, b = bval), e = 0 .. 1, maxsols = nsols)]

[0.8115199822e-1, .3189598393, .6884466500]

(13)

In terms of the parameters b and e and normalization constant B, the non-dimensionalized wavefunctions of the 3 regions are as below. The scale factor gives a simpler form and prevents 0/0 problems later in the calculation.

scale := `assuming`([denom(simplify(eval(left2, eqns)))], [positive]); left3 := `assuming`([simplify(eval(scale*left2, eqns))], [positive]); box3 := `assuming`([simplify(eval(scale*box2, eqns))], [positive]); right3 := `assuming`([simplify(eval(scale*right2, eqns))], [positive])

sin((1/2)*b*e^(1/2))*(-e+1)^(1/2)+cos((1/2)*b*e^(1/2))*e^(1/2)

 

B*e^(1/2)*exp((1/2)*b*(-e+1)^(1/2)*(2*X+1))

 

-(sin((1/2)*b*e^(1/2))*(e^(1/2)*sin(b*e^(1/2)*X)-(-e+1)^(1/2)*cos(b*e^(1/2)*X))-cos((1/2)*b*e^(1/2))*(cos(b*e^(1/2)*X)*e^(1/2)+sin(b*e^(1/2)*X)*(-e+1)^(1/2)))*B

 

B*exp(-(1/2)*b*(-e+1)^(1/2)*(-1+2*X))*(e^(1/2)*cos(b*e^(1/2))+(-e+1)^(1/2)*sin(b*e^(1/2)))

(14)

It remains to find the normalization constant B. The three parts of the normalization integral are:

P__L := `assuming`([int(left3^2, X = -infinity .. -1/2)], [positive]); P__box := `assuming`([int(box3^2, X = -1/2 .. 1/2)], [positive]); P__R := `assuming`([int(right3^2, X = 1/2 .. infinity)], [positive])

(1/2)*B^2*e/(b*(-e+1)^(1/2))

 

-(1/4)*B^2*(2*e^(1/2)*(-e+1)^(1/2)*cos(2*b*e^(1/2))-2*e^(1/2)*(-e+1)^(1/2)-2*b*e^(1/2)-2*e*sin(2*b*e^(1/2))+sin(2*b*e^(1/2)))/(b*e^(1/2))

 

(1/2)*B^2*(e^(1/2)*cos(b*e^(1/2))+(-e+1)^(1/2)*sin(b*e^(1/2)))^2/(b*(-e+1)^(1/2))

(15)

Solve for B. There are two (messy) solutions for B of opposite sign; it is conventional to choose the sign such that the ground state has positive values.

Bval := sort([solve(P__L+P__box+P__R = 1, B)])[2]

Assemble it into a single piecewise function.

`&Phi;__all` := eval(piecewise(X < -1/2, left3, `and`(X >= -1/2, X <= 1/2), box3, X > 1/2, right3), B = Bval)

Plot. Plots offset vertically by the energy as usual

Xmax := 1.5; psiscale := .15; colors := [red, blue, magenta]; wavefns := plot([seq(eval(psiscale*`&Phi;__all`, {b = bval, e = evals[i]})+evals[i], i = 1 .. nsols)], X = -Xmax .. Xmax, color = colors); walls := plot([-1/2, y, y = 0 .. 1], color = black), plot([1/2, y, y = 0 .. 1], color = black), plot(1, X = -Xmax .. -1/2, color = black), plot(0, X = -1/2 .. 1/2, color = black), plot(1, X = 1/2 .. Xmax, color = black); evalplot := plot(evals, X = -Xmax .. Xmax, linestyle = dash, color = colors); plots:-display(wavefns, walls, evalplot, axes = boxed, labels = [X, psiscale*Phi+E/V__0])

 

NULL

Download finite_box_non-dim2.mw

Comments
1. The first general comment is about the issue of how much Maple can do. In principle one should be able to give dsolve the three ODEs and the boundary conditions and it should output the result. We are still far away from that. Even for one region, the boundary conditions at infinity are not handled by dsolve. The other extreme is to solve the ODEs for their general solutions, and follow the algebraic manipulations for implementing the boundary conditions as one might do it on paper. Engel for example has a comment "At this point we notice that by dividing the equations in each pair, the coefficients can be eliminated to give [...]". Maple will not easily do that trick or the manipulations that led to the special form on which the trick is applied. Levine's textbook [2] gives a different non-intuitive set of steps.

But Maple can solve complicated equations, so I wanted a more general strategy that avoids as much as possible the requirement to manipulate into special forms. On the other hand, it is tempting (as @zenterix tried) to just give the three general solutions with 6 arbitrary constants and the boundary conditions to Maple's solve, and solve for the six constants. One finds that all six are zero. This us a consequence of the fact that the ODEs are linear, and misses the crucial point that it is an eigenvalue problem. So there must be some sort of step-by-step guidance for Maple and there is a general but non-obvious strategy to solving such problems.

2. The second general comment is that there is a trade-off between presenting the solution steps without any arcane Maple code, and getting to the solution efficiently and programmatically, without too many manual manipulations. One of my suggestions to @zenterix involved manually dividing both sides of an equations by a fairly complicated expression, to which @acer expressed a preference for programmatic solutions. At the time, I mainly did that to keep close the to existing solution, and was thinking that I usually set things up so that is not necessary. But I found here that I do it a lot, and it is a natural consequence of the interactive way I use Maple. Here's two examples:

In the second line of label (4), I originally got a more complicated form of de_outside, then manually figured out the factor to put inside simplify to get the form you see. I do this frequently with Maple, especially when I use dchange.

In the last line of label (8), I manually divided by B to remove it. Had B been in the denominator, I could have removed it programmatically with numer (an operation I use frequently, though it somewhat recklessly ignores denominator zeroes).

Programmatically doing things can be relatively unreadable and disrupt the readability for the non-Maple reader. For example in label (6) there is "extraneous" code to find which coefficient to set to zero so that the solution goes to zero at +/- infinity. This was forced on me since after generating the nice figure I re-ran the worksheet only to have multiple errors. I originally used eval(outside, {c__1 = B__L, c__2 = A__L}); to change Maple's dsolve constants to read the way I wanted. But I realized that dsolve does not reproducibly assign c__1 and c__2 to the same term each time, raising the general issue of: 

3. Session to session reproducibility. If I am only going to use a worksheet myself, I don't usually worry too much about this, since I can usually debug this fairly easily. On the other hand if the worksheet is for others, it needs to be foolproof. I have taken to always sorting the output of solve, e.g., the assignment to bval in the execution group after label (15). The code added for the dsolve constants works, but is non-trivial Maple (suffixed type testing). (Solving this issue for Eigenvectors is yet more difficult.)

4. Some efforts to make the worksheet more readable were hard to do.

- For some reason, Engel chose to call the two constants in the left region B and B'. Entering B*exp(-k*x) + B'*exp(k*x) in 2D leads to B(x)*exp(-k*x) + diff(B(x), x)*exp(k*x). No doubt this can be fixed, but I didn't pursue this.

- I would normally use upper case Psi for the non-dimensionalized psi, but Psi is the name of a special function in Maple. But wait, now we can use "local Phi;" to solve this problem. However diff(Psi(x),x,x) displays as Psi(2,x), so I had to settle for Phi. (SCR submitted.)

- I build up the left wavefunctions incrementally as expressions assigned to left1, left2, etc, which is rather ugly. Why not use arrow procedures so we can use psi(x), D(psi)(x) etc. Aside from some awkwardness in updating such procedures by redefining them as needed, I ran into the following problem:

limit(A*exp(-k*x) + B*exp(k*x), x = infinity) assuming k > 0; gives as expected
signum(B)*infinity;

but

psi := x -> A*exp(-k*x) + B*exp(k*x);
limit(psi(x), x = infinity) assuming k > 0;
returns unevaluated. What happened to full evaluation?

- I'm used to entering hbar as hbar in 1D; it displays as h with the bar through. In 2-D entering hbar^2 is displayed nicely, but internally it is `&hbar;`. We can have the following puzzle:

(hbar/m)^2-`&hbar;`^2/m^2

hbar^2/m^2-`&hbar;`^2/m^2

NULL

- I originally wanted a vertical axis label Psi, E/V__0, but labels = [X, Psi, E/V__0] obviously won't work. It took some time to figure out the answer is to make "Psi, E/V__0" an atomic variable. I finally settled on the more honest, if cryptic, label shown.

5. solve gives an "invalid" solution. Originally I worked with solutions left2 etc (see label (6)) after simplify(eval(left2, eqns)). Every second wavefunction was about 10^9 times higher than the others, which was difficult to debug. It turns out the denominator of those wavefunctions was exactly zero but numerically 10^(-10), meaning they plotted as large-scaled versions of the right shape, without any division-by-zero error. The fix is to remove the denominators by scaling (see label (14)).

This is just a consequence of Maple giving generic solutions, and the only way around it is to be aware of it.

Summary

To solve such problems with Maple requires one to play around in an interactive way. After hacking to a solution, it can take some effort to make it presentable and usable to others. But the final result is pleasing, and is certainly much easier than working through the problem on paper. The ability to manipulate complicated expressions means circumventing tricks that might be needed in manual solutions. 

References
[1] T. Engel, Quantum Chemistry and spectroscopy. Pearson 2019, 4th ed. Sec. 5.1, Prob. 5.3. 
[2] I. N. Levine, Quantum Chemistry. Pearson 2009, 6th ed. Sec. 2.4. 

 

 

For Maple 17, in 2013, we introduced the GroupTheory package. It has seen a lot of improvements since its introduction, and I figured I would write something about how you can use it to teach a group theory course.

 

First of all, I think it would be a great idea to have your students just play with the GroupTheory package in Maple, and get some intuition for what makes group theory tick by getting their hands dirty. But that is not what I want to talk about today. Instead, I want to discuss how you might use it for giving your lectures - to show some visualizations while you show your beamer presentation or write on the black- or whiteboard.

 

When starting out with the definition of a group, you might want to compare the Cayley table of a group with that of a binary operation that doesn't define a group. A set with any binary operation is called a magma; to find good examples, we might want to use one group; one magma that has an identity and is associative but not invertible; and one magma that is has an identity and is invertible but not associative. Maybe we also want the group to not be cyclic (so the group order will have to not be prime), because those Cayley tables look a little boring. For this we can use the Magma package.

 

We note that a magma that is invertible and has an identity element is called a loop. We can enumerate all magmas of a given order and with certain properties using the command Magma:-Enumerate, finding either the number of such objects (by default) or a list of the multiplication tables (with the output = list option). Can we find interesting examples of order 4?

 

with(Magma)

Enumerate(4, group), Enumerate(4, loop), Enumerate(4, associative, identity)

2, 2, 35

(1)

 

No: all loops of order 4 are groups. Let's try order 6.

 

Enumerate(6, group), Enumerate(6, loop), Enumerate(6, associative, identity)

2, 109, 2237

(2)

 

Yes, we can find examples here. We find the Cayley tables of three suitable magmas; we call the non-cyclic group one m1, the non-associative loop one m2, and the non-invertible magma m3.

 

Enumerate(6, group, output = list)

(3)

"m1 := ?[2]:"

Enumerate(6, loop, output = list)[1 .. 5]

(4)

 

"m2 := ?[2]:"

Enumerate(6, associative, identity, output = list)[1 .. 5]

(5)

 

Most of these appear to have many more of one value than of another (e.g., many more threes). Let's find one where that is not so extreme. For example, we might want to minimize the standard deviation of the frequencies of the values occurring in the Cayley table.

 

lst := Enumerate(6, associative, identity, output = list)

lst := remove(IsLeftInvertible, lst)

numelems(lst)

2235

(6)

frequencies := map(proc (m) options operator, arrow; map2(numboccur, m, [seq(1 .. 6)]) end proc, lst)``

with(Statistics)

sds := map(StandardDeviation, convert(frequencies, 'set'))

{HFloat(2.449489742783178), HFloat(3.0983866769659336), HFloat(3.1622776601683795), HFloat(3.22490309931942), HFloat(3.286335345030997), HFloat(3.3466401061363027), HFloat(3.4058772731852804), HFloat(3.4641016151377544), HFloat(3.464101615137755), HFloat(3.521363372331802), HFloat(3.5213633723318023), HFloat(3.5777087639996634), HFloat(3.6331804249169903), HFloat(3.687817782917155), HFloat(3.7416573867739413), HFloat(3.794733192202055), HFloat(3.8470768123342687), HFloat(3.847076812334269), HFloat(3.898717737923586), HFloat(3.9496835316262997), HFloat(3.9496835316263), HFloat(3.9999999999999996), HFloat(4.0), HFloat(4.049691346263318), HFloat(4.09878030638384), HFloat(4.147288270665544), HFloat(4.195235392680606), HFloat(4.1952353926806065), HFloat(4.2895221179054435), HFloat(4.33589667773576), HFloat(4.3817804600413295), HFloat(4.427188724235731), HFloat(4.47213595499958), HFloat(4.5166359162544865), HFloat(4.560701700396552), HFloat(4.604345773288535), HFloat(4.604345773288536), HFloat(4.6475800154489), HFloat(4.69041575982343), HFloat(4.732863826479693), HFloat(4.774934554525329), HFloat(4.77493455452533), HFloat(4.8166378315169185), HFloat(4.857983120596447), HFloat(4.898979485566356), HFloat(4.9396356140913875), HFloat(4.939635614091388), HFloat(4.979959839195493), HFloat(5.019960159204453), HFloat(5.059644256269407), HFloat(5.0990195135927845), HFloat(5.138093031466052), HFloat(5.176871642217914), HFloat(5.215361924162119), HFloat(5.253570214625479), HFloat(5.291502622129181), HFloat(5.329165037789691), HFloat(5.366563145999495), HFloat(5.403702434442518), HFloat(5.440588203494177), HFloat(5.477225575051661), HFloat(5.513619500836089), HFloat(5.549774770204643), HFloat(5.585696017507577), HFloat(5.621387729022079), HFloat(5.656854249492381), HFloat(5.692099788303083), HFloat(5.727128425310542), HFloat(5.761944116355173), HFloat(5.796550698475776), HFloat(5.830951894845301), HFloat(5.865151319446072), HFloat(5.8991524815010505), HFloat(5.93295878967653), HFloat(5.932958789676531), HFloat(5.966573556070519), HFloat(6.0), HFloat(6.0332412515993425), HFloat(6.066300355241241), HFloat(6.066300355241242), HFloat(6.099180272790763), HFloat(6.131883886702357), HFloat(6.164414002968976), HFloat(6.196773353931867), HFloat(6.228964600958975), HFloat(6.260990336999411), HFloat(6.29285308902091), HFloat(6.324555320336759), HFloat(6.356099432828282), HFloat(6.418722614352485), HFloat(6.48074069840786), HFloat(6.511528238439883), HFloat(6.542170893518451), HFloat(6.572670690061994), HFloat(6.603029607687671), HFloat(6.603029607687672), HFloat(6.6332495807108), HFloat(6.663332499583073), HFloat(6.6932802122726045), HFloat(6.693280212272605), HFloat(6.723094525588644), HFloat(6.723094525588645), HFloat(6.752777206453653), HFloat(6.782329983125268), HFloat(6.811754546370561), HFloat(6.928203230275509), HFloat(6.957010852370435), HFloat(6.985699678629192), HFloat(7.014271166700073), HFloat(7.042726744663604), HFloat(7.0710678118654755), HFloat(7.127411872482185), HFloat(7.155417527999327), HFloat(7.183313998427188), HFloat(7.18331399842719), HFloat(7.293833011524188), HFloat(7.429670248402684), HFloat(7.4565407529228995), HFloat(7.4565407529229), HFloat(7.483314773547883), HFloat(7.536577472566709), HFloat(7.53657747256671), HFloat(7.563068160475615), HFloat(7.64198926981712), HFloat(7.77174369109018), HFloat(7.8993670632526), HFloat(7.92464510246358), HFloat(7.9498427657407165), HFloat(8.024961059095553), HFloat(8.12403840463596), HFloat(8.366600265340756), HFloat(8.390470785361211), HFloat(8.390470785361213), HFloat(8.414273587185052), HFloat(8.438009243891594), HFloat(8.508818954473059), HFloat(8.854377448471462), HFloat(8.87693640846886), HFloat(8.921883209278185), HFloat(9.338094023943), HFloat(9.338094023943002), HFloat(9.359487165438072), HFloat(9.81835016690686), HFloat(9.818350166906862), HFloat(10.295630140987)}

(7)

 

Aha, the smallest standard deviation is a bit under two and a half, and the next possible value is greater than 3. Let's examine the Cayley tables that show this standard deviation.

NULL

small_sd_index := select(proc (i) options operator, arrow; StandardDeviation(frequencies[i]) < 3 end proc, [seq(1 .. numelems(frequencies))])

[1636, 1638, 2234, 2235]

(8)

small_sd := lst[small_sd_index]

(9)

 

The last of these looks interesting.

 

m3 := small_sd[-1]

NULL

Now we can display these three Cayley tables:

CayleyColorTable(m1); CayleyColorTable(m2); CayleyColorTable(m3)

 

It's clear that the multiplication shown in the third Cayley table is not invertible (because multiplying by any element other than 1, on either side, is not a permutation of the elements: rows and columns beyond the first don't have all colors). It's less visually obvious that the second Cayley table doesn't show an associative multiplication, but a quick loop showed that 5*(3*3) = 5*5 and 5*5 = 4 whereas 3*(3*5) = 3 and 3 = 3. I'm not sure if there is something real underpinning this, but to my mind this is a nice parallel to the fact that when you're proving a set with a given operation is a group, it's easier to show that there are inverses than that the operation is associative.

 

A second nice visualization, also usable in the first week or two of a group theory course, is also named after Cayley: Cayley graphs. Here is a Cayley graph for the dihedral group D[3] of order 6:

 

with(GroupTheory)

D3 := DihedralGroup(3)

_m132248572811840

(10)

with(GraphTheory)

DrawGraph(CayleyGraph(D3), layout = spring)

 

NULL

Here is a well-known presentation of the alternating group on 4 letters. I find "grabbing and turning" the 3D plot shows the structure much better than simply an embedding of the graph in the plane.

 

a4 := `<|>`(`<,>`(a, b), `<,>`(a^3, b^2, a.b.a = b.(a^2).b))

_m132249105458016

(11)

DrawGraph(CayleyGraph(a4), layout = spring, dimension = 3, size = [800, 800])

 

 

Another great opportunity for a visualization comes a couple of weeks later, when you talk about subgroup lattices. Here are a few examples:

 

with(GroupTheory)``

qd := QuasiDihedralGroup(2)

_m132249751531168

(12)

GroupOrder(qd)

16

(13)

DrawSubgroupLattice(qd, normal = false, center = false)

 

 

This is the plain subgroup lattice. Note how the subgroups in the first and second nontrivial "layer" from the bottom are grouped by conjugacy class. The default visualization of a subgroup lattice highlights the centre in light blue and the (in this case six) other normal subgroups in green.

 

DrawSubgroupLattice(qd)

 

 

We see that every conjugacy class of size one is a normal subgroup. We can also highlight other subgroups, if we want. Maybe we want to show which are the (cyclic) subgroups generated by one of the chosen generators:

 

generators := Generators(qd)

[_m132249751506336, _m132249751509600]

(14)

DrawSubgroupLattice(qd, highlight = [seq({g}, `in`(g, generators))])

 

 

Of course you can also show more advanced topics in this way. For example, here is the Frattini series of this group.

 

DrawSubgroupLattice(qd, highlight = FrattiniSeries(qd))

 

NULL NULL


 

Download blogpost-algebra.mw

With the new release of Maple Flow 2024.2 the units "Area" and "Speed" don't work.

I run a MaxBook Pro with macOS Sequoia 15.2 and uninstalled MF2024.2.

 

Major deficiency in Physics[Vectors]; Distinct sets of basis vectors are not recognized!

You can't define vectors in alternative bases like: {\hat{i}',\hat{j}',\hat{k}'} or {\hat{i}_{1},\hat{j}_{2},\hat{k}_{3}}.

This deficiency has been around for a while. I have found other posts regarding this problem.

The deficiency greatly reduces the allowable calculations with Physics[Vector].

Are there any plans to fix this?

Here is my example which shows this deficiency in more detail.

physics_vectors_and_multiple_unit_vectors.mw
 

restart

NULL

NULL

with(Physics[Vectors])

[`&x`, `+`, `.`, Assume, ChangeBasis, ChangeCoordinates, CompactDisplay, Component, Curl, DirectionalDiff, Divergence, Gradient, Identify, Laplacian, Nabla, Norm, ParametrizeCurve, ParametrizeSurface, ParametrizeVolume, Setup, Simplify, `^`, diff, int]

(1)

NULL

Crucial Deficiency in Physics[Vectors]

 

NULL

I can only guess the purpose of the Physics[Vectors] package from reviewing it's corresponding help documentation. My interpretation of the documentation leads me to believe that the package is best used for generating vector equation formulas in different coordinate bases of a SINGLE coordinate system.

 

This means one can easily generate position vector expressions such as:

 

r_ = _i*x+_j*y+_k*z

r_ = _i*x+_j*y+_k*z

(1.1)

Cylindrical Position Vector

 

The position vector in a cylindrical basis is given by:

 

r_ = ChangeBasis(rhs(r_ = _i*x+_j*y+_k*z), 2)

r_ = (x*cos(phi)+y*sin(phi))*_rho+(cos(phi)*y-sin(phi)*x)*_phi+z*_k

(1.1.1)

r_ = ChangeBasis(rhs(r_ = _i*x+_j*y+_k*z), 2, alsocomponents)

r_ = _k*z+_rho*rho

(1.1.2)

NULL

NULLNULLNULL

Spherical Position Vector

 

NULL

r_ = ChangeBasis(rhs(r_ = _i*x+_j*y+_k*z), 3)

r_ = (y*sin(phi)*sin(theta)+x*sin(theta)*cos(phi)+z*cos(theta))*_r+(y*sin(phi)*cos(theta)+x*cos(phi)*cos(theta)-z*sin(theta))*_theta+(cos(phi)*y-sin(phi)*x)*_phi

(1.2.1)

r_ = ChangeBasis(rhs(r_ = _i*x+_j*y+_k*z), 3, alsocomponents)

r_ = r*_r

(1.2.2)

NULL

NULL

As is known from the vector analysis of curvilinear coordinate systems the basis vectors can depend on the coordinates in question.

 

In cylindrical, the basis vectors are

 

_rho = ChangeBasis(_rho, 1)

_rho = _i*cos(phi)+sin(phi)*_j

(1.2)

_phi = ChangeBasis(_phi, 1)

_phi = -sin(phi)*_i+cos(phi)*_j

(1.3)

and in spherical, the basis vectors are

 

_r = ChangeBasis(_r, 1)

_r = sin(theta)*cos(phi)*_i+sin(theta)*sin(phi)*_j+cos(theta)*_k

(1.4)

_theta = ChangeBasis(_theta, 1)

_theta = cos(theta)*cos(phi)*_i+cos(theta)*sin(phi)*_j-sin(theta)*_k

(1.5)

_phi = ChangeBasis(_phi, 1)

_phi = -sin(phi)*_i+cos(phi)*_j

(1.6)

NULL

NULL

NULL

Example of this Deficiency using Biot-Savart Law

 

NULL

Biot-Savart law can be used to calculate a magnetic field due to a current carrying wire. The deficiency in question can be observed by explicity constructing the integrand in the Biot-Savart integral defined below.

NULL

NULL

NULL

In electrodynamics, quantum mechanics and applied mathematics, it is common practice to define a position of observation by a vector `#mover(mi("r"),mo("&rarr;"))` and a position of the source responsible for generating the field by a vector diff(`#mover(mi("r"),mo("&rarr;"))`(x), x).

 

It is just as common to define the difference in these vectors as

 

l_ = r_-(diff(r(x), x))*_

l_ = r_-`r'_`

(1.3.1)

and thus

 

dl_ = dr_-(diff(dr(x), x))*_

dl_ = dr_-`dr'_`

(1.3.2)

as found in the integrand of the Biot-Savart integral.

NULL

It suffices to consider `#mover(mi("l"),mo("&rarr;"))` = `#mover(mi("r"),mo("&rarr;"))`-`#mover(mi("r'"),mo("&rarr;"))` in a cylindrical basis for this argument.

 

The observation position is:

 

`#mover(mi("r"),mo("&rarr;"))` = rho*`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`+z*`#mover(mi("k"),mo("&and;"))`

NULL

The source position is:

 

diff(`#mover(mi("r"),mo("&rarr;"))`(x), x) = (diff(z(x), x))*(diff(`#mover(mi("k"),mo("&and;"))`(x), x))+(diff(rho(x), x))*(diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x))

NULL

`#mover(mi("l"),mo("&rarr;"))` = `#mover(mi("r"),mo("&rarr;"))`-(diff(`#mover(mi("r"),mo("&rarr;"))`(x), x)) and `#mover(mi("r"),mo("&rarr;"))`-(diff(`#mover(mi("r"),mo("&rarr;"))`(x), x)) = z(x)*`#mover(mi("k"),mo("&and;"))`-(diff(z(x), x))*(diff(`#mover(mi("k"),mo("&and;"))`(x), x))+rho*`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`-(diff(rho(x), x))*(diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x))

NULL

The deficiency in question arises because MAPLE cannot define multiple unit vectors in distinct bases such as {`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`, diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x)} or {`#mscripts(mi("&rho;",fontstyle = "normal"),mn("1"),none(),none(),mo("&and;"),none(),none())`, `#mscripts(mi("&rho;",fontstyle = "normal"),mn("2"),none(),none(),mo("&and;"),none(),none())`}.  These pairs of unit vectors arise naturally, as shown above in Biot-Savart law.

NULL

If we look at `#mover(mi("&rho;",fontstyle = "normal"),mo("&circ;"))` and  diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&circ;"))`(x), x) generally, they look like:

NULL

`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))` = `#mover(mi("i"),mo("&and;"))`*cos(phi)+sin(phi)*`#mover(mi("j"),mo("&and;"))`

NULL

diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x) = (diff(`#mover(mi("i"),mo("&and;"))`(x), x))*cos(diff(phi(x), x))+sin(diff(phi(x), x))*(diff(`#mover(mi("j"),mo("&and;"))`(x), x))

NULL

If the bases vectors {`#mover(mi("i"),mo("&and;"))`, `#mover(mi("j"),mo("&and;"))`, `#mover(mi("k"),mo("&and;"))`} and {diff(`#mover(mi("i"),mo("&and;"))`(x), x), diff(`#mover(mi("j"),mo("&and;"))`(x), x), diff(`#mover(mi("k"),mo("&and;"))`(x), x)} are Cartesian and are not related related through rotations so that

NULL

"(i)*i' =(|i|)*|i'|*cos(0)=1"``NULL

NULL

"(j)*(j)' =(|j|)*|(j)'|*cos(0)=1"NULL

NULL

"(k)*(k)' =(|k|)*|(k)'|*cos(0)=1 "

NULL

and so,NULL

 

`#mover(mi("i"),mo("&circ;"))` = diff(`#mover(mi("i"),mo("&circ;"))`(x), x)

NULL

`#mover(mi("j"),mo("&circ;"))` = diff(`#mover(mi("j"),mo("&circ;"))`(x), x)

NULL

`#mover(mi("k"),mo("&circ;"))` = diff(`#mover(mi("k"),mo("&circ;"))`(x), x)

NULL

the radial unit vectors in cylindrical are then,

 

`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))` = `#mover(mi("i"),mo("&and;"))`*cos(phi)+sin(phi)*`#mover(mi("j"),mo("&and;"))`

NULL

diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x) = `#mover(mi("i"),mo("&and;"))`*cos(diff(phi(x), x))+sin(diff(phi(x), x))*`#mover(mi("j"),mo("&and;"))`

NULL

In typical problems, the anglular location of the observation point, φ, is distinct from the angular location of the source, diff(phi(x), x) and so under this condition, `#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))` <> diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x).

 

Consider the classic problem of the magnetic field due to a circular current carrying wire. Surely, the angular coordinate of one location of the current carrying wire  is different from the angular coordinate  of an observation point hovering above and off-axis on the other side of the current carrying wire. See figure below.

NULL

NULL

NULL

NULL

Therefore,

 

`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))` <> diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x)

NULL

NULL

What happens in MAPLE when you try to define a second distinct unit vector diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x)?

NULL

One can easily find `#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`.

NULL

_rho

_rho

(1.3.3)

NULL

NULLIf you try to define diff(`#mover(mi("&rho;",fontstyle = "normal"),mo("&and;"))`(x), x) ...

 

 

diff(_rho(x), x)

`_rho'`

(1.3.4)

So using a prime doesn't work.

NULL

You could try a numbered subscript...

`_&rho;__2`

_rho__2

(1.3.5)

but that doesn't work.

 

You could try an indexed unit vector...

NULL

_rho[2]

_rho[2]

(1.3.6)

which can be define but is not recognized by Physics[Vectors] since...

 

NULL

ChangeBasis(_rho[2], 1)

Error, (in Physics:-Vectors:-Identify) incorrect indexed use of a unit vector: _rho[2]

 

NULL

And so it's just not possible with the current implementation.

``

``

NULL

NULL


 

Download physics_vectors_and_multiple_unit_vectors.mw

 

 

Maple Transactions has just published the Autumn 2024 issue at mapletransactions.org

From the header:

This Autumn Issue contains a "Puzzles" section, with some recherché questions, which we hope you will find to be fun to think about.  The Borwein integral (not the Borwein integral of XKCD fame, another one) set out in that section is, so far as we know, open: we "know" the value of the integral because how could the identity be true for thousands of digits but yet not be really true? Even if there is no proof.  But, Jon and Peter Borwein had this wonderful paper on Strange Series and High Precision Fraud showing examples of just that kind of trickery.  So, we don't know.  Maybe you will be the one to prove it! (Or prove it false.)

We also have some historical papers (one by a student, discussing the work of his great grandfather), and another paper describing what I think is a fun use of Maple not only to compute integrals (and to compute them very rapidly) but which actually required us to make an improvement to a well-known tool in asymptotic evaluation of integrals, namely Watson's Lemma, just to explain why Maple is so successful here.

Finally, we have an important paper on rational interpolation, which tells you how to deal well with interpolation points that are not so well distributed.

Enjoy the issue, and keep your contributions coming.

We have just released updates to Maple and MapleSim.

Maple 2024.2 includes ability to tear away tabs into new windows, improvements to scrollable matrices, corrections to PDF export, small improvements throughout the math engine, and moreWe recommend that all Maple 2024 users install this update.

This update also include a fix to the problem with the simplify extension mechanism, as first reported on MaplePrimes. Thanks, as always, for helping us make Maple better.

This update is available through Tools>Check for Updates in Maple, and is also available from the Maple 2024.2 download page, where you can find more details.

At the same time, we have also released an update to MapleSim, which contains a variety of improvements to MapleSim and its add-ons. You can find more information on the MapleSim 2024.2 download page.

The tab key, and the mouse can be used to trigger completion selection in Maple 2024.1 like previous versions. 

For interface resposiveness, a new option (disabled by default) has been added to the interface tab of Maple 2024.1 Options (available from the Tools menu). Users that prefer to use enter to trigger completion selection can enable the option. 

Change the option here and apply to the session or globally if using enter to trigger completion selection is preferred.

This is a task from one forum:  “Let's mark an arbitrary point on the circle. Let's draw a segment from this point, perpendicular to the diameter, and draw a circle, the center of which is at this point, and the radius is equal to this segment. Let's mark the intersection point of the segment connecting the intersection points of the circles with the perpendicular segment. Prove that the locus of all such points is an ellipse.”
I wanted to get a picture of a numerically animated "proof" using Maple tools.

МАTH_HЕLP_PLANET.mw
 And in fact, it turned out that AB=2AC, or AC=BC.

From a discussion about expanding unit expressions with compound units I concluded that expanding derived units such as Newton, Watt, Volt, Tesla,... to SI base units is difficult in Maple.

Unintentionally, I came across a rather simple solution for SI units.

toSIbu := x -> x = Units:-Unit(simplify(x/Unit('kg'))*Unit('kg'));

converts derived SI units to SI base units. It’s the inverse of what the units packages and simplify do (i.e. simplification to derived units).

What makes it maybe more interesting: It also works, again unintentionally, on other units than SI units. If, one day, you come along an erg or a hartree or or a kyne and you cannot guess the SI units convert/units needs, try

toSIbu(Unit('pound'));
toSIbu(Unit('hp'));
toSIbu(Unit('electron'));
toSIbu(Unit('hartree'));
toSIbu(Unit('bohr'));
toSIbu(Unit('barye'));
toSIbu(Unit('kyne'));
toSIbu(Unit('erg'));
toSIbu(Unit(mile/gal(petroleum)));

Maybe handy one day when you do not trust AI or the web.


 

NULL 

toSIbu := x -> x = Units:-Unit(simplify(x/Unit('kg'))*Unit('kg')):
toSIbu(Unit('N'));
toSIbu(Unit('J'));
toSIbu(Unit('W'));
toSIbu(Unit('Pa'));
toSIbu(Unit('C'));
toSIbu(Unit('F'));
toSIbu(Unit('S'));
toSIbu(Unit('H'));
toSIbu(Unit('T'));
toSIbu(Unit('V'));
toSIbu(Unit('Wb'));
toSIbu(Unit('Omega'));
toSIbu(Unit('lx'));
toSIbu(Unit('lm'));
toSIbu(Unit('degC'));
toSIbu(Unit('rad'));
toSIbu(Unit('sr'));

Units:-Unit(N) = Units:-Unit(m*kg/s^2)

 

Units:-Unit(J) = Units:-Unit(m^2*kg/s^2)

 

Units:-Unit(W) = Units:-Unit(m^2*kg/s^3)

 

Units:-Unit(Pa) = Units:-Unit(kg/(m*s^2))

 

Units:-Unit(C) = Units:-Unit(A*s)

 

Units:-Unit(F) = Units:-Unit(A^2*s^4/(m^2*kg))

 

Units:-Unit(S) = Units:-Unit(A^2*s^3/(m^2*kg))

 

Units:-Unit(H) = Units:-Unit(m^2*kg/(A^2*s^2))

 

Units:-Unit(T) = Units:-Unit(kg/(A*s^2))

 

Units:-Unit(V) = Units:-Unit(m^2*kg/(A*s^3))

 

Units:-Unit(Wb) = Units:-Unit(m^2*kg/(A*s^2))

 

Units:-Unit(`&Omega;`) = Units:-Unit(m^2*kg/(A^2*s^3))

 

Units:-Unit(lx) = Units:-Unit(cd/m^2)

 

Units:-Unit(lm) = Units:-Unit(cd)

 

Units:-Unit(`&deg;C`) = Units:-Unit(K)

 

Units:-Unit(rad) = Units:-Unit(m/m(radius))

 

Units:-Unit(sr) = Units:-Unit(m^2/m(radius)^2)

(1)

NULL


 

Download toSIbu.mw


(All done with Maple 2024 without loading any package)

 

 

 

This is another attempt to tell about one way to solve the problem of inverse kinematics of a manipulator.  
We have a flat three-link manipulator. Its movement is determined by changing three angles - these are three control parameters. 1. the first link rotates around the black fixed point, 2. the second link rotates around the extreme movable point of the first link, 3. the third link − around the last point of the second link. These movable points are red. (The order of the links is from thick to thin.) The working point is green. For example, we need it to move along a circle. But the manipulator has one extra mobility (degree of freedom), that is, the problem has an infinite number of solutions. We have the ability to remove this extra degree of freedom mathematically. And this can also be done in an infinite number of ways.
Let us give two examples where the same manipulator performs the same movement of the working point in different ways. In one case the last red point moves in a straight line, and in the other case it moves in an ellipse. The result is the same. In the corresponding program texts, the manipulator model is described by a system of nonlinear equations f1, f2, f3, f4, f5 relative to the coordinates of the ends of the links (very easy to understand). The specific additional connection that takes away one degree of freedom is highlighted in blue. Equation of a circle in red color.

1.mw

2.mw


And as an elective. The same circle was obtained using a spatial 3-link manipulator with 5 degrees of freedom. In the last text, blue and red colors perform the same functions as in the previous texts.
3.mw

 

VerifyTools is a package that has been available in Maple for roughly 24 years, but until now it has never been documented, as it was originally intended for internal use only. Documentation for it will be included in the next release of Maple. Here is a preview:

VerifyTools is similar to the TypeTools package. A type is essentially a predicate that a single expression can either satisfy or not. Analogously, a verification is a predicate that applies to a pair of expressions, comparing them. Just as types can be combined to produce compound types, verifications can also be combined to produce compund verifications. New types can be created, retrieved, queried, or deleted using the commands AddType, GetType (or GetTypes), Exists, and RemoveType, respectively. Similarly in the VerifyTools package we can create, retrieve, query or delete verifications using AddVerification, GetVerification (or GetVerifications), Exists, and RemoveVerification.

The package command VerifyTools:-Verify is also available as the top-level Maple command verify which should already be familiar to expert Maple users. Similarly, the command VerifyTools:-IsVerification is also available as a type, that is,

VerifyTools:-IsVerification(ver);

will return the same as

type(ver, 'verification');

The following examples show what can be done with these commands. Note that in each example where the Verify command is used, it is equivalent to the top-level Maple command verify. (Also note that VerifyTools commands shown below will be slightly different compared to the Maple2024 version):

with(VerifyTools):

Suppose we want to create a verification which will checks that the length of a result has not increased compared to the expected result. We can do this using the AddVerification command:

AddVerification(length_not_increased, (a, b) -> evalb(length(a) <= length(b)));

First, we can check the existence of our new verification and get its value:

Exists(length_not_increased);

true

GetVerification(length_not_increased);

proc (a, b) options operator, arrow; evalb(length(a) <= length(b)) end proc

For named verifications, IsVerification is equivalent to Exists (since names are only recognized as verifications if an entry exists for them in the verification database):

IsVerification(length_not_increased);

true

On the other hand, a nontrivial structured verification can be checked with IsVerification,

IsVerification(boolean = length_not_increased);

true

whereas Exists only accepts names:

Exists(boolean = length_not_increased);

Error, invalid input: VerifyTools:-Exists expects its 1st argument, x, to be of type symbol, but received boolean = length_not_increased

The preceding command using Exists is also equivalent to the following type call:

type(boolean = length_not_increased, verification);

true

Now, let's use the new verification:

Verify(x + 1/x, (x^2 + 1)/x, length_not_increased);

true

Verify((x^2 + 1)/x, x + 1/x, length_not_increased);

false

Finally, let's remove the verification:

RemoveVerification(length_not_increased);

Exists(length_not_increased);

false

GetVerification(length_not_increased);

Error, (in VerifyTools:-GetVerification) length_not_increased is not a recognized verification

GetVerifications returns the list of all verifications known to the system:

GetVerifications();

[Array, FAIL, FrobeniusGroupId, Global, Matrix, MultiSet, PermGroup, RootOf, SmallGroupId, Vector, address, after, approx, array, as_list, as_multiset, as_set, attributes, boolean, box, cbox, curve, curves, dataframe, dataseries, default, default, dummyvariable, equal, evala, evalc, expand, false, float, function, function_bounds, function_curve, function_shells, greater_equal, greater_than, in_convex_polygon, indef_int, interval, less_equal, less_than, list, listlist, matrix, member, multiset, neighborhood, neighbourhood, normal, permute_elements, plot, plot3d, plot_distance, plotthing_compile_result, polynom, procedure, ptbox, range, rational, record, relation, reverse, rifset, rifsimp, rtable, set, sign, simplify, sublist, `subset`, subtype, superlist, superset, supertype, symbol, table, table_indices, testeq, text, true, truefalse, type, undefined, units, vector, verifyfunc, wildcard, xmltree, xvm]

Download VerificationTools_blogpost.mw

Austin Roche
Software Architect
Mathematical Software
Maplesoft

Circles inscribed between curves can be specified by a system of equations relative to the coordinates of the center of the circle and the coordinates of the tangent points. Such a system can have 5 or 6 equations and 6 variables, which are mentioned above.
In the case of 5 equations, we can immediately obtain an infinite set of solutions by selecting the ones we need from it. 
(See the attached text for more details.)
The 1st equation is responsible for the belonging of the point of tangency to one of the curves.
The 2nd equation is responsible for the belonging of the point of tangency to another curve.
In the 3rd equation, the points of tangency on the curves belong to the inscribed circle.
In the 4th and 5th equations, the condition is satisfied that the tangents to the curves are perpendicular to the radii of the circle at the points of contact.
The 6th equation serves either to find a specific inscribed circle or to find an infinite set of solutions. It is selected based on the type of curves and their mutual arrangement.

In this example, we search for a subset of the solution set using the Draghilev method by solving the first five equations of the system: we inscribe circles in two "angles" formed by the intersection of the exponent and the ellipse.
The text of this example, its solution in the form of a picture,"big" option and pictures of similar examples.

INSCRIBED_CIRCLES.mw


 


Addition 09/01/24, 
One curve for the first two equations in coordinates x1,x2 and x3,x4
f1:=
 x1^2 - 2.5*x1*x2 + 3*x2^2 - 1;
f2:=
 x3^2 - 2.5*x3*x4 + 3*x4^2 - 1;

This is a reminder that presentation applications for the Maple Conference are due July 17, 2024.

The conference is a a free virtual event and will be held on October 24 and 25, 2024.

We are inviting submissions of presentation proposals on a range of topics related to Maple, including Maple in education, algorithms and software, and applications. We also encourage submission of proposals related to Maple Learn. You can find more information about the themes of the conference and how to submit a presentation proposal at the Call for Participation page.

I encourage all of you here in the Maple Primes community to consider joining us for this event, whether as a presenter or an attendee!

Kaska Kowalska
Contributed Program Co-Chair

 

The Proceedings of the Maple Conference 2023 is now out, at

mapletransactions.org

The presentations these are based on (and more) can be found at https://www.maplesoft.com/mapleconference/2023/full-program.aspx#schedule .

There are several math research papers using Maple, an application paper by an undergraduate student, an engineering application paper, and an interesting geometry teaching paper.

Please have a look, and don't forget to register for the Maple Conference 2024.

We have just released an update to Maple. Maple 2024.1 includes improvements to the math engine, PDF export, the Physics package, command completion, and more. As always, we recommend that all Maple 2024 users install this update. In particular, please note that this update includes fixes to ODESteps and simplifying integrals, as reported on Maple Primes. Thanks for helping us, and other users, by letting us know!

At the same time, we have also released an update to MapleSim. MapleSim 2024.1.1 includes improvements to FMU import/export, plotting, co-simulation, and more, as well as enhancements to the Web Handling Library.

These updates are available through Tools>Check for Updates in Maple or MapleSim, and are also available from the Download Product Updates section of our web site, where you can find more details.

1 2 3 4 5 6 7 Last Page 1 of 65