acer

32363 Reputation

29 Badges

19 years, 332 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

Every new time that you utilize assume to place an assumption on a name that causes the creation of a new, separate instance of that name.

You might think of it somwhat similarly to creating a new escaped local (ie. when a procedure returns one of its locally declared names, unassigned).

Such names are distinct from each other. They are stored at distinct addresses in memory. They do not combine or cancel arithmetically.

A similar thing happens if you do the following in a single session (ie. no restart, no save&read).

1) place assumption on x. 2) assign that to f. 3) place another assumption on x using `assume` instead of `additionally`. 4) now try to use x and f together.

Yes, in your case you used the very same quality in the assumption. But that's not what's making them different. What makes them different/distinct instances of the name `x` is that they had assumptions placed at different times.

Names parsed from strings are always parsed as the global instance. So by that action both name instances become the same global name. And so those then cancel by subtraction.

ps. saving assumed or local names to .m or .mla is poor practice.

No, they are not the same.

And, no, this is not a bug in mint. The two cases are different, and documented as such.

If you don't protect against evaluation then the case using the bracketed syntax runs the risk that the globally used names (or lexically scoped names) might have been assigned values.

So, to make that case mint-clean you'd want it as,

    MmaTranslator[':-Mma'][':-LeafCount']

This aspect is discussed in the fourth bullet-point of the Description Section (and last Example) of the colondash Help-page.

So, the message by mint for your example is just as it ought to be. This is a typical situation for which that mint warning is intended; it warns you that if the higher scope name has an assigned value then your code will behave wrongly. The bug is in your code, ie. in using the unquoted global name like that.

nb. Since ideally you have to add uneval quotes and :- to the bracketed/indexed syntax, it's actually shorter and less typing to use the other form. The indexed reference is a relatively poor choice to use, in general.

Also, yes, mint is actively maintained.

If a procedure has,
   option remember, system
then its remember table items can get cleared off when garbage collection occurs.

If that's underdesirable then some entries could be made permanent instead, using say Cache:-AddPermanent.

If a procedure has just,
  option remember
then garbage collection won't clear its "classical" remember table. (A subsop(4=NULL,eval(myproc)) can still clear it off, if done manually.)

The interplay between a procedure's cache and garbage collection is discussed on the Cache Help-page. That page mentions, "The option cache is incompatible with options remember and system.", ie. a procedure cannot utilize both flavours of memoization, cache tables and "classical" remember tables. The option cache mechamism is reasonbly flexible, but a procedure that utilizes it cannot also utilize option remember, system.

[edit] The option remember mechanisms are very old. The Cache system is relatively newer (though, now, old too), intended as a more modern (organized, flexible) mechanism.

It seems that plots:-display is triggering a re-draw, and mishandling the domain merge.

A workaround, leaving color and other look&feel aspects as they were:

plots:-display(
   plot(1, x=0..1, redraw=false),
   plot(1, x=2..3, redraw=false));

This issue also appears for me in the latest Beta-testing-period development version. So I have submitted a bug report, as it appears to not be fixed yet.

ps. I'm not seeing the bug if the plotted expression is not constant, ie. if it actually depends on x.

I prefer a way that doesn't require the manual entering of multiplicative factors for cancellation.

restart

Levine - Ch. 2.4 - Particle in a Rectangular Well

assume(G <> 0, C <> 0, E < V__0, m > 0, E > 0)

interface(showassumed = 0)

 

s__1 := sqrt(2*m*(V__0-E))/`&hbar;` = 2^(1/2)*(m*(V__0-E))^(1/2)/`&hbar;`NULL

s__2 := -s__1 = -2^(1/2)*(m*(V__0-E))^(1/2)/`&hbar;`NULL

NULLs := sqrt(2*m*E)/`&hbar;` 

`&psi;__1`, `&psi;__2` and `&psi;__3` are wavefunctions.

`&psi;__1` := proc (x) options operator, arrow; C*exp('s__1'*x) end proc = proc (x) options operator, arrow; C*exp('s__1'*x) end procNULL

`&psi;__2` := proc (x) options operator, arrow; A*cos('s'*x)+B*sin('s'*x) end proc = proc (x) options operator, arrow; A*cos('s'*x)+B*sin('s'*x) end procNULL

`&psi;__3` := proc (x) options operator, arrow; G*exp('s__2'*x) end proc = proc (x) options operator, arrow; G*exp('s__2'*x) end procNULL

Some of the boundary conditions involve the first derivatives of the wavefunctions.

`&psi;__1,d` := D(`&psi;__1`) = proc (z) options operator, arrow; C*s__1*exp(s__1*z) end procNULL

`&psi;__2,d` := D(`&psi;__2`) = proc (z) options operator, arrow; -A*s*sin(s*z)+B*s*cos(s*z) end procNULL

`&psi;__3,d` := D(`&psi;__3`) = proc (z) options operator, arrow; G*s__2*exp(s__2*z) end procNULL

expr1 := isolate(`&psi;__1`(0) = `&psi;__2`(0), C) = C = ANULL

Next, I solve the third boundary condition and sub in the result from solving the first boundary condition. We get B in terms of A.

expr3 := combine(eval(solve(`&psi;__1,d`(0) = `&psi;__2,d`(0), {B}), expr1)) = {B = A*((V__0-E)/E)^(1/2)}NULL

Next, consider the second boundary condition

expr2 := isolate(`&psi;__2`(l) = `&psi;__3`(l), G) = G = -(-A*cos(s*l)-B*sin(s*l))/exp(s__2*l)NULL

We can obtain G in terms of just A by subbing in previously found relationships, as follows

expr2 := collect(combine(eval(expr2, expr3)), [sin, cos])

G = A*((V__0-E)/E)^(1/2)*exp(2^(1/2)*(m*(V__0-E))^(1/2)*l/`&hbar;`)*sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)+A*cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)*exp(2^(1/2)*(m*(V__0-E))^(1/2)*l/`&hbar;`)

Finally, consider the fourth boundary condition.

expr4 := combine(eval(isolate(`&psi;__2,d`(l) = `&psi;__3,d`(l), G), expr3))

G = -A*(((V__0-E)/E)^(1/2)*cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)-sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`))*(E/(V__0-E))^(1/2)*exp(2^(1/2)*(m*(V__0-E))^(1/2)*l/`&hbar;`)

result := eval(expr4, expr2)


Shorter way:

indets(result, specfunc(sin))[1]; combine(simplify(isolate(result, %)))

sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`) = 2*(E*(V__0-E))^(1/2)*cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)/(2*E-V__0)


Alternate (manual handling of common factor):

collect((lhs-rhs)(result)/(A*exp(sqrt(2)*sqrt(m*(V__0-E))*l/`&hbar;`)), [sin, cos], `@`(combine, simplify))

(-2*E+V__0)*(1/(E*(V__0-E)))^(1/2)*sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)+2*cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)


Longer way:

temp := collect(result/(A*exp(sqrt(2)*sqrt(m*(V__0-E))*l/`&hbar;`)), [sin, cos], `@`(combine, simplify))

((V__0-E)/E)^(1/2)*sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)+cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`) = (E/(V__0-E))^(1/2)*sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)-cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)

combine(simplify((rhs-lhs)(map[2](select, has, temp, sin))) = simplify((lhs-rhs)(map[2](select, has, temp, cos))))

(2*E-V__0)*(1/(E*(V__0-E)))^(1/2)*sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`) = 2*cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)


Yet another way to clear off the common factors (eg. `A`, exp(...)) in the rhs and lhs of the `result` expression.
We divide both rhs and lhs of `result` by its rhs.

This is even less ad hoc then the other ways; we don't need to know to `isolate` for a sin term, and nor do we have to manually enter any factors to clear off.

temp2 := normal(simplify((proc (u) options operator, arrow; u/rhs(u) end proc)(result), size)-1)

-(((V__0-E)/E)^(1/2)*cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)*(E/(V__0-E))^(1/2)-(E/(V__0-E))^(1/2)*sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)+((V__0-E)/E)^(1/2)*sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)+cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`))/((((V__0-E)/E)^(1/2)*cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)-sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`))*(E/(V__0-E))^(1/2)) = 0


Now, with the lhs of that being zero, we take the numerator of that as being zero.
collect(map(numer, temp2), [sin, cos], `@`(combine, simplify))

(2*E-V__0)*(1/(E*(V__0-E)))^(1/2)*sin(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`)-2*cos(2^(1/2)*(m*E)^(1/2)*l/`&hbar;`) = 0

NULL

Download solve_constants_accc.mw

a few notes:
1) Put all your assume/additonally calls at the start, before you start forming expressions involving the assumed names. Otherwise you can end up with different variables/names instances that look the same but are distinct from each other.
2) Use 2-argument eval instead of subs, to substitute methematically (rather than structurally). Even if you can get the same results here, using either. Still do it. It's a mathematically better approach in general, ie. some say, some other example.
3) Note that simplify (with no arguments) can actually undo (expand) some of the radical simplifictions that you seem to want and which you can get using combine.
4) For this example's steps of solving for G, the isolate command can be used without needing solve (and thus avoid both warnings about assumptions as well as solve's useassumptions option).

The central reason is that the ortiginal and some particular combined form don't attain the same value for all flavours of values of the parameters. The combine/simplified formula depends on the nature of the parameters (eg, their signs, or relative signs, even if taken as purely real).

Note that in your latter example, using simplify(...,[..]) ie. simplify-with-side-relations, the substitution won't happen unless the product to be replaced is actually present, and combining the relevent radicals runs into the same kinds of considerations as in your first example.

restart;

expr1:=A*sqrt(-m*(-V__0 + E))/sqrt(m*E)

A*(-m*(-V__0+E))^(1/2)/(m*E)^(1/2)

The first question I have is why the "m's don't cancel."


A central reason is that the result of such cancellation depends
on the nature of the variables inside the radical.

Compare the following next two results, which are different in value,
when E<0 and E<V__0, according to whether m<0 or m>0.

simplify(expr1) assuming m>0, E<0, E<V__0;

-I*A*(V__0-E)^(1/2)/(-E)^(1/2)

simplify(expr1) assuming m<0, E<0, E<V__0;

I*A*(V__0-E)^(1/2)/(-E)^(1/2)

Notice that the following conditions produce the same result.

simplify(expr1) assuming m>0, E>0, E<V__0;
simplify(expr1) assuming m<0, E>0, E<V__0;

A*(V__0-E)^(1/2)/E^(1/2)

A*(V__0-E)^(1/2)/E^(1/2)

Some other circumstances may also attain your expected result.

simplify(combine(expr1)) assuming m*E>0;

A*((V__0-E)/E)^(1/2)

Next, consider the expression

expr2:=exp(sqrt(2)*sqrt(m)*sqrt(-V__0 + E)*l*I/`&hbar;`)

exp(I*2^(1/2)*m^(1/2)*(-V__0+E)^(1/2)*l/`&hbar;`)

Why doesn't the simplification below work?

This is because
"sqrt(m) sqrt(-`V__0`+E) is not always equal to  sqrt(m*(-`V__0`+E)) . "
It's the same kind of thing going on, as in the earlier example.

simplify(expr2,[2*m*(E-V__0)=y])

exp(I*2^(1/2)*m^(1/2)*(-V__0+E)^(1/2)*l/`&hbar;`)

combine(expr2) assuming m>0;
simplify(%, [2*m*(E-V__0)=y]);

exp(I*l*2^(1/2)*(m*(-V__0+E))^(1/2)/`&hbar;`)

exp(I*l*y^(1/2)/`&hbar;`)

Download simplify_roots_ac.mw

You could also evaluate at various numeric values, and confirm the differences.

Sometimes, with 2D Input mode, What You See Is Not What You Get.

If I copy & paste the input (that gives your output Label (5)) then even as 2D Input the pasted entry looks different from what I copied. That I is actually parsed as a 1, even if the input doesn't look like it. If I paste it in as 1D Input then I see that the line has actually been parsed as,

    `psi__I,d` := unapply(diff(psi__1(x), x), x)

Similarly, the 2D Input on the line with your output Label (6) is actually,

    `psi__1,d`(x)

So, this is all a muddle. I don't know what you did in your Maple 2022 to get such an effect, sorry. Note that in such mysterious circumstances you can copy&paste 2D Input to a 1D Execution Group, to see what is actually going on with the parsed input.

Btw, there is a better way to do such functional differentiation, by using the D command (which was designed for just this kind of purpose). Eg,

restart

`&psi;__1` := proc (x) options operator, arrow; C*exp(a*x) end proc

proc (x) options operator, arrow; C*exp(a*x) end proc

`&psi;__1,d` := D(`&psi;__1`)

proc (x) options operator, arrow; C*a*exp(a*x) end proc

`&psi;__1,d`(x)

C*a*exp(a*x)

restart

`&psi;__I` := proc (x) options operator, arrow; C*exp(a*x) end proc

proc (x) options operator, arrow; C*exp(a*x) end proc

`&psi;__I,d` := D(`&psi;__I`)

proc (x) options operator, arrow; C*a*exp(a*x) end proc

`&psi;__I,d`(x)

C*a*exp(a*x)

NULL

Download psi_subscript_ac.mw

@nm My experiments indicate that it is not the fact that the nested procedure is anonymous that makes the difference to mint. But rather, it's the fact that the anonymous procedure is immediately, functionally applied that makes the difference to mint.

For example, I can apply an anonymous procedure using %, and mint reports as you'd expected. Or I can map an anonymous procedure across a list, say, and again mint reports as expected on the anonymous procedure. And those happen even if nested within another procedure. Eg,

foo := proc()
  local C1,y,x;
  map( proc()
         C1:= `tools/genglobal`(_C);
         sol:=y(x)=  C1;
       end proc, [ ]);
end proc:

For which my M2023.2 mint reports,

Nested Anonymous Procedure proc() on lines 3 to 6
  These global variables start with an _:  _C
  These local variables were assigned a value, but otherwise unused:  sol
  These local variables were not declared explicitly:  sol
Procedure foo() on lines 1 to 7
  These local variables were used but never assigned a value:  x, y

Apart from the aspects of whether the nested proc is assigned to some name (and what procname might produce, "unknown", etc...), I don't believe that its own behavior wrt locals, etc, differs according to whether it's anonymous or anonymous and immediately applied. Presuming that I've understood your followup points, I suspect that you're mainly just seeing a difference in what mint happens to report upon.

Your surfdata example worked properly up until Maple 2023.2. It doesn't work in Maple 2024.1.1 and 2024.2. I will submit a regression bug report.

But you can still work around that easily, by wrapping in plots:-display and passing the scaling option to that instead.

restart

N := 20; M := LinearAlgebra:-RandomMatrix(N, generator = rand(0 .. .2))

plots:-display(plots:-surfdata(M, 0 .. 1, 0 .. 1, labels = ["x", "y", "V"]), scaling = constrained, size = [600, 600])

Download Scaled_matrix_plot_with_axes_ac.mw

You can use custom tickmarks for the matrixplot approach.

restart; N := 20; M := LinearAlgebra:-RandomMatrix(N, generator = rand(0 .. .2))

plots:-matrixplot(N*M, labels = ["x", "y", "V"], scaling = constrained, axis = [tickmarks = [seq(i = evalf((i-1)/(N-1)), i = 1 .. N, (N-1)*(1/5))]], size = [400, 400])

Download Scaled_matrix_plot_with_axes_ac2.mw

Sometimes rendering of custom end-ticks can visually clobber each other, if the values are "long", upon manual rotation. (I've reported that previously...) So generally I prefer using surfdata to using matrixplot for such examples.

As far as the implicitplot command goes, the view option is not for specifying the ranges of the curves, in the sense of what data is used to compute them. It's just for specifying the limits of the axes and how far all features may extend visually (presuming they've been constructed to extend that far).

Your four can be done in a single call to implicitplot, so I've rolled them together. I've kept the order in which you had them, which denotes how they get visually layered (ie. the green appears on top).

ps. The implicitplot command is a relatively inefficient way to construct lines, though that's not really noticeable as a one-off. So I leave it as you have chosen it.

restart

l := 2*x+y+1 = 0; l1 := 4*x+2*y+2 = 0; l2 := 4*x+2*y-2 = 0; l3 := 4*x-2*y+6 = 0

2*x+y+1 = 0

4*x+2*y+2 = 0

4*x+2*y-2 = 0

4*x-2*y+6 = 0

plots:-implicitplot([l, l1, l2, l3], x = -2 .. 1, y = -2 .. 5, color = [black, red, blue, green], legend = [l, l1, l2, l3], thickness = [5, 1, 1, 1])


 

Download The_intersection_parallelism_and_coincidence_of_two_straight_lines_ac.mw

Your code mistakenly passed gridline as an option to the Explore command, rather than the plotting command that Explore is calling. Below, gridline is passed as an option to DensityPlot itself.

The range option of DensityPlot can be used to specify the horizontal range (domain). You could utilize this to force a common range for all the parameter values. I am not sure if that aspect is what was bothering you.

Explore(Statistics:-DensityPlot(Statistics:-RandomVariable(Normal(mu, sigma)),
                                range = -2-9 .. 2+9, gridlines),
        mu = -2 .. 2, sigma = 0.5 .. 3)

I couldn't quite figure out from your Question whether you wanted the left- and right sums plotted together, or whether you wanted one sequence after the other.

restart

with(Student:-Calculus1)

G := plot(x^2, x = -3 .. 3)

plots:-animate(proc (N) options operator, arrow; plots:-display(RiemannSum(x^2, x = 0 .. 2, method = right, output = plot, partition = trunc(N), caption = ""), RiemannSum(x^2, x = 0 .. 2, method = left, output = plot, partition = trunc(N), caption = "", boxoptions = [filled = [color = "Burgundy"]]), title = (n = trunc(N))) end proc, [n], n = 1 .. 25, frames = 25, background = G, paraminfo = false, size = [800, 300])

NULL

Download S7_Riemann_Animation_Aire_ac.mw

You can tweak the look&feel as you wish.

Note that this overall plot is made up of several parts, each of which you can include or not. The plots:-display command combines them.

There are separate Help pages for the textplot, arrow, plot, and pointplot commands.

This is not the only way to construct something that looks like your image.

restart

randomize()

a := evalf[2]((rand(3 .. 4.0))()); b := evalf[2]((rand(0 .. 3.0))())

3.4

1.9

opts := thickness = 2, linestyle = dash; plots:-display(plot([x, b, x = -1.5 .. 4.5], color = blue, opts), plot([a, y, y = -1.5 .. 3.5], color = orange, opts), plottools:-arrow([a, 3.5], [a, 3.8], 0., .17, .8, color = orange), plottools:-arrow([a, -1.6], [a, -1.9], 0., .17, .8, color = orange), plottools:-arrow([4.5, b], [4.8, b], 0., .17, .8, color = blue), plottools:-arrow([-1.5, b], [-1.8, b], 0., .17, .8, color = blue), plots:-textplot([a, b, sprintf("(%a,%a) \n", a, b)], align = [above, left]), plots:-textplot([a, 4.0, x = a]), plots:-textplot([4.9, b, y = b], align = right), plots:-pointplot([[a, b]], symbol = solidcircle, symbolsize = 20), view = [-2 .. 5, -2.5 .. 4.5])

 

 

Download xa_yb_plot_ac.mw

An example is,

    -(signum(n)-1)/2

plot( -(signum(n)-1)/2, n=-10..10,
       thickness=6, size=[500,100], axes=box );


ps. Of course you could also write that as (1-signum(n))/2

Copy&Pasting from pretty-printed 2D Output seems like a mistake to me. Why not construct your string as you want it, and then line-print it, and then Copy&Paste from that.

You can line-print your string, intead of pretty-printing it as 2D Output.

When line-printed, the escaped backslashes are displayed as in the actual string.

You can have your procedure itself do the line-printing (in addition to returning the string). Or you can line print the result afterwards.

You can line-print using either the lprint or printf commands.

For example,

restart;

MyTableElement2 := proc(L::list(nonnegint))
  ## L will have only two elements
  local M, x, y, res;
  M:=L;
  x:=convert(M[1],string);
  y:=convert(M[2],string);

  res :=  cat("\\begin{tabular}{c} ",x," \\\\ \\hline ",y," \\end{tabular}");

  printf("%a", res);

  return res;

end:

 

out := MyTableElement2([2,3]);

\\begin{tabular}{c} 2 \\\\ \\hline 3 \\end{tabular}

"\begin{tabular}{c} 2 \\ \hline 3 \end{tabular}"

 

lprint( out );

\\begin{tabular}{c} 2 \\\\ \\hline 3 \\end{tabular}


Download lineprinted_string.mw

First 6 7 8 9 10 11 12 Last Page 8 of 336