acer

32303 Reputation

29 Badges

19 years, 309 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

Maple stores only one instance of the polynomial in memory. That allows it to be immediately recognized as being the same instance -- wherever it earlier appeared -- which is a basic aspect of Maple crucial to efficiency.

And sort acts in-place on that stored instance.

Notice that this uniquification also takes place if you re-enter the expression.

restart;

res:= x^2 + x + 1 + 1/3*x^3 + 1/12*x^4 + 1/60*x^5 + 1/360*x^6 + 1/2520*x^7;

   x^2+x+1+1/3*x^3+1/12*x^4+1/60*x^5+1/360*x^6+1/2520*x^7

sort(res);

   1/2520*x^7+1/360*x^6+1/60*x^5+1/12*x^4+1/3*x^3+x^2+x+1

res;

   1/2520*x^7+1/360*x^6+1/60*x^5+1/12*x^4+1/3*x^3+x^2+x+1

x^2 + x + 1 + 1/3*x^3 + 1/12*x^4 + 1/60*x^5 + 1/360*x^6 + 1/2520*x^7;

   1/2520*x^7+1/360*x^6+1/60*x^5+1/12*x^4+1/3*x^3+x^2+x+1

It would be catastrophically bad for Maple if it has to walk multiple instances of such expressions whose terms were differently ordered, whenever it has to test that they were equivalent.

This behavior is documented on the Help page for sort, which states in its Description section,

   Note: Sorting polynomials is a destructive operation: the input polynomial is sorted "in-place".

That Help pages also states, in its Thread Safety section,

   The sort command is thread safe as of Maple 15, provided that a polynomial is not being sorted.  Sorting polynomials is not thread safe.

Try it as,

   f := unapply(PolynomialFit(4, M, x), x);

ps. FYI, the word function has a technical meaning in Maple, which is different from this. A better term in the context of Maple (and which you used in your title), is that you want to create a procedure or operator from the returned expression. That could then be applied to arguments, eg, f(3), etc,

If M is your Matrix with all entries of type numeric then,

    ImageTools:-Create(M)

You could use the background option of the plot command, with ranges set according to image dimensions.

Then you get the usual 2-D plot point-probe facilities.

You could scale down the image (max. used dimension <300, say), and retain aspect ratio, to reduce burden on GUI.

Flip/flop as needed.

Here is one way.

sort([x,x/3],key=content);

[(1/3)*x, x]


If you have trouble using this more generally then the cause is your lack of a correspondingly more general example.

Perhaps you could set up a custom indexing function, used alongside storage=sparse.

You could use the rtable_scanblock command for this.

(I'll add a timing, to compare with some other suggestions. It's not clear whether you need it to be very quick.)

restart;

(m,n) := 6,10^5;

6, 100000

M := LinearAlgebra:-RandomMatrix(m,n,density=0.3):

 

First, using just the 3rd row.

 

rtable_scanblock(M[3,..],[1..n],':-NonZeros');

29751

 

Now, for all rows, and measuring performance.

 

CodeTools:-Usage(
   [seq(rtable_scanblock(M[i,..],[1..n],':-NonZeros'),i=1..m)]
);

memory used=4.58MiB, alloc change=3.06MiB, cpu time=18.00ms, real time=17.00ms, gc time=0ns

[29954, 29739, 29751, 29914, 29949, 29709]

ZerosInRow := i -> numelems(op(M[i])[2]):

CodeTools:-Usage(
   [seq(ZerosInRow(i),i=1..m)]
);

memory used=18.05MiB, alloc change=7.53MiB, cpu time=138.00ms, real time=138.00ms, gc time=69.12ms

[29954, 29739, 29751, 29914, 29949, 29709]

with(LinearAlgebra):
CodeTools:-Usage(
   nops~(select~(x -> x <> 0, convert~([Row(M, [1 .. RowDimension(M)])], list)))
);

memory used=29.58MiB, alloc change=12.87MiB, cpu time=200.00ms, real time=200.00ms, gc time=0ns

[29954, 29739, 29751, 29914, 29949, 29709]

Download rtable_scanblock.mw

@emendes Yes, I meant if you added style=line to plots:-odeplot.

I realize that a connected curve the default behaviour here. But doing so explicitly adds a STYLE(LINE) plotting substructure into the result.

In the past there have been some rare 3D plotting export problems where such a change made the key difference. So I thought I might as well see whether it makes a difference to you here.

You're code produces an array-plot, for which the GUI uses a slightly different mechanism. Does the problem occur if either plot is shown without the encapsulating Array?

The uniquification you show for inequalities if not due to the items being placed within a set. It occurs when the inequalities are first constructed. That is a kind of canonicalization.

But equalities are just one aspect of a syntax ( eg. a=b ) which has many other uses in Maple than representing a mathematical equivalence (for solving purposes, etc).

An equality is a Maple syntax that is also used to specify equivalences for substitution (2-argument eval, subs, simplify with side-relations), specifying options for procedure calls, and several other purposes. In these, the rhs versus lhs positions are a crucial part of the syntax.

It is therefore important that equalities can be generally programatically manipulated, including retaining their integrity under enclosure within data structures.

It would be wrong for equalities to uniquify (under set construction, say) as if the lhs/rhs aspect did not make them different. In general Maple usage, they are different.

Direct top-level input of an int call can produces these messages that you find useful. Part of that utility is due (according to some people) to the absence of a burden on the user to adjust a setting -- ie. it's automatic.

For Library routines that are performing broader computations such messaging arising from internal use of the int command would be mostly undesirable.

A goal is to balance supplying helpful information versus flooding unwanted messages.

There are a great many such instances of Library procedures that call int, and to manage this balance of messaging there is a mechanism within the integration subsystem which handles userinfo-style messages, hints, and warnings.

As a start, see the calls to kernelopts(level) inside,
   showstat(int::Exact)
(or more specifically, showstat(int::Exact,33) in Maple 2023.0).

_EnvIntWarning := evalb(kernelopts('level') <= 64
         or kernelopts('level') <= 128 and _Env_assuming_recursion_level = 0);

As you've noticed here, a tricky case involves using value(Int(...)) versus int, eg.,
   value(Int(1/(sqrt(x__0 - x)*sqrt(-x^2 + 1)), x = 0 .. x__0));
If you query kernelopts(level) in the debugger, for the following code under Maple 2023.0, then you may see a value higher than the relevant cutoff. But increasing the cutoff could induce an unwanted flood of messages from other Library code, and so this might be a difficult case to "get just right".

restart;
kernelopts(opaquemodules=false):
stopat(int:-Exact,33);
value(Int(1/(sqrt(x__0 - x)*sqrt(-x^2 + 1)), x = 0 .. x__0));

Managing the whole mechanism is complicated. Memoization effects (remembered results of prior computation), accomodating various (internal) enviroment variables, and a deeper level for top-level input in 2-D Input mode, may also need to be factored in.

There are other parts to this mechanism, and I haven't given a complete explanation. But, even aside from complications of the implementation, the balancing of the situations in which such messages appearing automatically for, say, top-level input versus not appearing for internal Library code is difficult.

You're showing assignments to the "hat" names. If you do that then any rewrite in terms of them will evaluate to your original. So I suggest not making those assignments.

Instead, set them up as equations. And you'll need the new names on the rhs of the equations to be utilized.

restart

eqn2new := rho*V*(diff(x(t), t)) = (conjugate(x)-x)*w+(x__2-`#mscripts(mi("x"),mn("2"),none(),none(),mo("&macr;"),none(),none())`)*w__2+(x__1-`#mscripts(mi("x"),mn("1"),none(),none(),mo("&macr;"),none(),none())`)*w__1

rho*V*(diff(x(t), t)) = (conjugate(x)-x)*w+(x__2-`#mscripts(mi("x"),mn("2"),none(),none(),mo("&macr;"),none(),none())`)*w__2+(x__1-`#mscripts(mi("x"),mn("1"),none(),none(),mo("&macr;"),none(),none())`)*w__1

seqns := [`#mover(mi("x"),mo("&circ;"))` = conjugate(x)-x, `#mscripts(mi("x"),mn("1"),none(),none(),mo("&circ;"),none(),none())` = x__1-`#mscripts(mi("x"),mn("1"),none(),none(),mo("&macr;"),none(),none())`, `#mscripts(mi("x"),mn("2"),none(),none(),mo("&circ;"),none(),none())` = x__2-`#mscripts(mi("x"),mn("2"),none(),none(),mo("&macr;"),none(),none())`]

[`#mover(mi("x"),mo("&circ;"))` = conjugate(x)-x, `#mscripts(mi("x"),mn("1"),none(),none(),mo("&circ;"),none(),none())` = x__1-`#mscripts(mi("x"),mn("1"),none(),none(),mo("&macr;"),none(),none())`, `#mscripts(mi("x"),mn("2"),none(),none(),mo("&circ;"),none(),none())` = x__2-`#mscripts(mi("x"),mn("2"),none(),none(),mo("&macr;"),none(),none())`]

revseqns := `~`[rhs = lhs](seqns)

[conjugate(x)-x = `#mover(mi("x"),mo("&circ;"))`, x__1-`#mscripts(mi("x"),mn("1"),none(),none(),mo("&macr;"),none(),none())` = `#mscripts(mi("x"),mn("1"),none(),none(),mo("&circ;"),none(),none())`, x__2-`#mscripts(mi("x"),mn("2"),none(),none(),mo("&macr;"),none(),none())` = `#mscripts(mi("x"),mn("2"),none(),none(),mo("&circ;"),none(),none())`]

subs(revseqns, eqn2new)

rho*V*(diff(x(t), t)) = w*`#mover(mi("x"),mo("&circ;"))`+w__1*`#mscripts(mi("x"),mn("1"),none(),none(),mo("&circ;"),none(),none())`+w__2*`#mscripts(mi("x"),mn("2"),none(),none(),mo("&circ;"),none(),none())`

eval(eqn2new, revseqns)

rho*V*(diff(x(t), t)) = w*`#mover(mi("x"),mo("&circ;"))`+w__1*`#mscripts(mi("x"),mn("1"),none(),none(),mo("&circ;"),none(),none())`+w__2*`#mscripts(mi("x"),mn("2"),none(),none(),mo("&circ;"),none(),none())`

Download subsrev.mw

Naturally, you could alternatively form the equations directly with the new names on the rhs. (I just thought that you might be interested in knowing how to reverse them.)

note: I cannot tell from your image whether you want the overbars denote conjugates, or to be part of atomic names (atomic identifiers, as via right-click menu 2-D Math -> Convert To -> Atomic variables). I'm supposing that you know which you want, and will enter them accordingly.

plots:-pointplot([Re, Im]~(uu10000));

You can, of course, add options such as symbol, symbolsize, color, etc.

@C_R As you've seen, one aspect of your original approach is that f(x__0) gets evaluated with x__0 being a mere name. In this case you encountered problems with that.

That aspect is sometimes called "premature evaluation", with a problem ensuing because procedure f is not handling a mere name as you'd prefer. The aspect is that procedure f is being called before its argument gets an actual numeric value.

Previously you were given some ways in which the root-finding could be accomplished (using Maple 2021 at the time).

Your procedure f was defined as,
   f := x__0 -> int(1/sqrt(sin(x__0) - sin(x)), x = 0 .. x__0)

Note that for,
    fsolve(f(x__0) = 2*sqrt(alpha), x__0 = 0 .. 0.9*Pi/2)
the call f(x__0) for x__0 a mere name occurs before fsolve ever receives any arguments. The call f(x__0) is being evaluated prematurely.

In my Maple 2023.0 the approach of delaying the evaluation of f(x__0) does succeed, ie,
    g := alpha -> fsolve('f(x__0) = 2*sqrt(alpha)', x__0 = 0 .. Pi*1/2*0.9):
    g(0.6336176953);

produces the answer 0.5614162053. It is slow, taking about 75 seconds, because the numeric integrations are not fast.

For me, it doesn't take "forever". But it's slow. It's slow because the way in which the numeric integrations are requested makes them slow (not because fsolve itself is slow).

You had used a so-called operator calling sequence in a call to plot. That's another way to avoid the call f(x__0) for x__0 a name. A similar approach for fsolve can also avoid the premature evaluation. This too takes about 75 seconds for me.
   g := alpha -> fsolve(f - 2*sqrt(alpha), 0 .. Pi*1/2*0.9):
   g(0.6336176953);

At the risk of being irritating, I'll mention that (as shown before), with a bit of care using numeric integration can do well here. Here's a slightly different tweak that I showed before (which was a coarser error tolerance with a slightly higher working precision).
    f := x__0 -> int(1/sqrt(sin(x__0) - sin(x)), x = 0 .. x__0, method = _d01ajc):
    g := alpha -> fsolve(f - 2*sqrt(alpha), 0 .. Pi*1/2*0.9):
    g(0.6336176953);

That produces the answer 0.5614162054 in less that one second, for me.

As Preben has shown, the integral can be solved symbolically under assumptions and a procedure formed from the result using unapply. Previously I too had shown a symbolic integration under assumptions, using Maple 2021 and a change of variables, followed by unapply. The ensuing fsolve attempt is very fast. As you've seen, cases that do not do well here include that in which the integration is attempted symbolically but without the key assumptions.

The most notable aspect of your worksheet is that you have formed the equation (1) before you assign values with units to the parameters. You don't have to do it that way, but I will retain that approach because it's key to some of the things you've noticed.

restart

with(Units)

Automatically loading the Units[Simple] subpackage
 

 

`&alpha;__1` = arctan(l__1*sin(alpha)/(l__1*cos(alpha)+l__2))

alpha__1 = arctan(l__1*sin(alpha)/(l__1*cos(alpha)+l__2))

(1)

l__1 := 50*Unit('mm')

l__2 := 40*Unit('mm')
alpha := 120*Unit('deg')

combine(alpha__1 = arctan(l__1*sin(alpha)/(l__1*cos(alpha)+l__2)), units)

alpha__1 = arctan((5/3)*3^(1/2))

(2)

:-simplify(alpha__1 = arctan(l__1*sin(alpha)/(l__1*cos(alpha)+l__2)))

alpha__1 = arctan((5/3)*3^(1/2))

(3)

Units:-Standard:-simplify(alpha__1 = arctan(l__1*sin(alpha)/(l__1*cos(alpha)+l__2)))

alpha__1 = arctan((5/3)*3^(1/2))

(4)

simplify(alpha__1 = arctan(l__1*sin(alpha)/(l__1*cos(alpha)+l__2)))

alpha__1 = arctan(5*sin(120*Units:-Unit(arcdeg))/(5*cos(120*Units:-Unit(arcdeg))+4))

(5)

Now the the parameters have been assigned their values
with units, entered input gets parsed with the rebound
arithmetic operators.

`&alpha;__1` = arctan(l__1*sin(alpha)/(l__1*cos(alpha)+l__2))

alpha__1 = arctan((5/3)*3^(1/2))

(6)

Download units_after.mw

If the Units (or Units:-Simple, or Units:-Standard) package is loaded then the arithmetic operators `+` and `*` are rebound to package exports of the same names, which are units-aware.

The reason why it works directly if you "retype" the input (after assigning values with units to the parameters) is that the input gets parsed using those units-aware versions.

But your original equation (1) is formed before the parameters have values with units. And so the resulting expression contains calls to the original global (units-unaware) arithmetic operators. Mere re-evaluation does not reparse, or re-utilize the rebound units-aware versions, even after the parameters are assigned values with units.

It is unfortunate that Units:-Simple:-simplify is inadequate here, taking longer and not getting the desired result. I will submit a bug report against that aspect. But combine(...,units) or the global :-simplify do fine.

Based on your description, you might consider line-printing, eg.

restart;

with(StringTools):

S := $1..20;

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20

Ls := SubstituteAll(String([S])[2..-2]," ",""):

lprint~([LengthSplit(Ls,10)]):

1,2,3,4,5,
6,7,8,9,10
,11,12,13,
14,15,16,1
7,18,19,20

printf~("%s\n",[LengthSplit(Ls,10)]):

1,2,3,4,5,
6,7,8,9,10
,11,12,13,
14,15,16,1
7,18,19,20

 

Download lineprint_ex1.mw

Your complete requirements are not clear, based only on your original Question. Is a fixed width font wanted? Could your "output" contain non-ASCII characters? Does all whitespace need to be removed? What did you mean by the trailing "/", if something other than the linebreaks? Etc.

First 48 49 50 51 52 53 54 Last Page 50 of 336