acer

33141 Reputation

29 Badges

20 years, 190 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are replies submitted by acer

@Kitonum Yes, that was one of the points I made in my previous Answer.

I'll move that paragraph from the end to the top of my Answer, in the hope it doesn't get missed.

Sorry, I missed that you also asked about possibly hiding the Slider's tickmark(value) labels(markers).

You can do that in the Explore call like so,

Explore(plot(sin(a*x),gridlines),
        parameters=[[a=-3.0..3.0,showlabels=false]]);

That hides them if you find them too large in font-size, but wouldn't help completely with extra white-space issue that you mentioned.

The syntax idea in the above code snippet is that when you use the longer-form for specifying the Explore parameters, ie,
    Explore(..., parameters=[ [...], [...] ] )
then you can add options specific to each Slider/ComboBox/other-controller within those sublists. See the programmatic Slider constructor Help-page.

You can also right-click on the Sliders in the (already embedded) exploration assembly, and change this Component Property via the popup menu.

Why did you start using this account instead of your old one?

A couple of interesting weaknesses,

restart;

kernelopts(version);

`Maple 2024.2, X86 64 LINUX, Oct 29 2024, Build ID 1872373`

ff := -I*((-1)^(1/9)+1)*(2*(-1)^(5/9)-2*(-1)^(4/9)+1)*1/(-1+(-1)^(1/9));

-I*((-1)^(1/9)+1)*(2*(-1)^(5/9)-2*(-1)^(4/9)+1)/(-1+(-1)^(1/9))

evala(ff);

2*(-1)^(5/6)-I

evala(%); # not idempotent

-3^(1/2)

radnormal(ff); # dusty trusty

-3^(1/2)

restart;

gg := (2*(-1)^(17/18)-(-1)^(11/18)+3^(1/2))/((-1)^(1/9)-1);

(2*(-1)^(17/18)-(-1)^(11/18)+3^(1/2))/((-1)^(1/9)-1)

simplify(gg); # unchanged

(2*(-1)^(17/18)-(-1)^(11/18)+3^(1/2))/((-1)^(1/9)-1)

evala(gg);

-3^(1/2)

Download simp_rad_0x.mw

I'll submit bug reports against those two.

@C_R You also mentioned that Relational Round palette in the recent Question I cited (and for which that palette also contained symbols  `≅`  and  `⊈` under discussion there).

I didn't take the opportunity to make that palette visible at that time, so missed it again.

Vote up.

@C_R 

I think that the most sensible next thing to do would be to clearly define the type of expressions (and subexpressions) that you want handled. I don't think that's been explained yet, without it there's a lot of scope for misinterpretations/mis-implementation/etc.

It's not clear to me yet whether you want lists and sets handled. If you don't handle lists then the reconstructor could get confused by examples whose deconstructed form contains lists (that were allowed to pass through).

It's not clear whether you want type `=` handled (and, if so then you'd need to guard against inappropriate argument flattening of the operand sequence, or else things like,
    (f,g) = s
will become indistinguishable from f = (g,s), etc. If you want to handle equations then wrapping the two arguments (sides) in something seems possible. But you might need a special case for the reconstructor. (Using subsop to shoe-horn in arguments that are bare expression-sequences, to avoid flattening of arguments in a procedure call, can be problematic due to unevaluation.)

It doesn't seem as if type Not(atomic) alone represents those expressions you'd want handled. It gets awkward in the absence of a clear spec.

ps. Yes, the indexing operator `?[]` has a Help-page.

While that "too many levels of recursion" error cannot be caught by either try..catch or the deprecated traperror, it might be of some use that your example might be manipulated if that argument is in trigh form without the I.

For example, you might convert to trigh, sinh, or exp, and then simplify, and then optionally convert to say sin.

[edit] On another note, trying to pinpoint the internal cause of your error, this is an unfortunate side-effect (which might go back to at least Maple 16, 2012).

Clearing the remember table of sin, between that convert and the simplify, helps here.

Note that the sin(I/2*z) in the result from convert is unevaluated. Normally it would evaluate to I*sinh(z/2), but the unevaluated sin call has been added to sin's remember table. Also, `expand/sin` doesn't handle that well.

restart;

foo:=convert(WhittakerW(7/3,1,hypergeom([1],[2],z)),trig);

WhittakerW(7/3, 1, -(2*I)*exp((1/2)*z)*sin(((1/2)*I)*z)/z)

simplify(foo);

Error, (in expand/sin) too many levels of recursion

bar:=sin(I/2*z);

sin(((1/2)*I)*z)

expand(bar);

Error, (in expand/sin) too many levels of recursion

forget(sin);

foo;

WhittakerW(7/3, 1, 2*exp((1/2)*z)*sinh((1/2)*z)/z)

simplify(foo);

(1/108)*((108*exp(2*z)+(-360*z-216)*exp(z)+159*z^2+360*z+108)*WhittakerW(1/3, 1, 2*exp((1/2)*z)*sinh((1/2)*z)/z)-280*WhittakerW(-2/3, 1, 2*exp((1/2)*z)*sinh((1/2)*z)/z)*z*(z-(3/8)*exp(z)+3/8))/z^2

bar;

I*sinh((1/2)*z)

expand(bar);

I*sinh((1/2)*z)

restart;

sin(I/2*z):='sin(I/2*z)':

expand(sin(I/2*z));

Error, (in expand/sin) too many levels of recursion

Download expand_sin_p1.mw

Another fun kind of expression is a list that is indexed by an as-yet-abstract index.

By that I mean that the value of the index is not yet a concrete posint.

I mention this example because it's in vein with the topic under discussion.

I find it interesting because it can be reconstructed using op(0,..) and op(..), but it's another example where the reconstruction is not done by a function call to its own op(0,...) . By that I mean that it's not reconstructed simply via the function call  op(0,expr)( op(expr) ) .

restart;

expr := [a,b,c,d][ f(i) ]

[a, b, c, d][f(i)]

# Using the constructor `?[]`

`?[]`( [a,b,c,d], [ f(i) ] )

[a, b, c, d][f(i)]

# same as expr
#
lprint(%);

[a, b, c, d][f(i)]

op(0, expr)

[a, b, c, d]

op(expr)

f(i)

# Reconstruction of expr, but not using
# op(0,expr) as the constructor command

`?[]`( op(0, expr), [op(expr)] )

[a, b, c, d][f(i)]

Download list_rep_indexed01.mw

@dharr I find that I am also able to use the entity directly -- without the palette -- in 2D Input by using command-completion on the typed characters simeq   (The symbols shown in the popup are not quite right, but upon insertion of the item matching that name it gets inserted ok.)

I find that I can also add it to my Favorites palette by selecting & dragging from such a successful 2D Input.

An example came up four months ago of another symbol (that could be entered directly as a non-marked-up 1D string like an HTML entity, or entered as an already-marked-up 2D Input symbol by using command-completion or a palettes Favorites item).

@C_R It might be interesting to read why you appear to have focused on type atomic, though you have (now) explained that you want to deal with algebraic expressions.

@janhardo Your modification cannot handle indices which are themselves exression sequences, because it's using only op(1,k) rather than all of op(k) where k is the running index.

So it gets this example wrong,

toPrefix:=T->['table', seq([op(1,k),T[op(1,k)]], k in indices(T))]:

Warning, (in toPrefix) `k` is implicitly declared local

 

T1 := table([(f,g)=a,q=s]);

table( [( f, g ) = a, ( q ) = s ] )

T1[f,g];

a

toPrefix(T1);

[table, [f, T1[f]], [q, s]]

Download jh_tbl01.mw

A correction couldn't only be a change to use op(k) instead of op(1,k), since the list flattening would make the results ambiguous, unable to distinguish between (f,g)=a and f=(g,a).

Of course, it's also not using the overall approach "listlist"-style to recurse into the list (and/or `=`) representation.

As mentioned, I don't know whether the final goal includes rebulding the original expression. If it does then special-case handling would be need for even expressions like sets and lists.

Not that op(0,e) is not always the same programmatic constructor which would recreate an expression assigned to name e. Consider the following top-down (outside->inside) approach.

G := e -> `if`(e::atomic,e,[op(0,e),map(procname,[op(e)])[]]):

G( [a,b,c] );
                [list, a, b, c]

To rebuild, you could put the special-case handling for sets and lists (which are each an "expression") into either the deconstructor (G) or the reconstructor. By that I mean replacing the word list by `[]`, or set by `{}`, to get an actual constructor.

nb. I am aware that map(procname,[op(e)]) will flatten/conjoin expression-sequences, eg, the operands of, say, (f,g)=(s,t) are unrecoverably merged into a single expression sequence. I wrote earlier that I'd prefer to not flatten the arguments, but the OP's original example has a form which does not guard against it. Wrapping the arguments in lists could make reconstruction cases ambiguous; but wrapping in some special dummy call like, say, __(...) could work.

Moving on, there are also unevaluated expressions, which are still a kind of "expression". They may evaluate to something other than themselves. Would you want to prevent evaluation of such, and if so in the calling of the procedure or in the procedure itself?

restart;


I'll use e::atomic, though I think I prefer a more targeted type check approach,
whether in a top-down recursion or not.

G := e -> `if`(e::atomic,e,[op(0,e),map(procname,[op(e)])[]]):

 

expr1 := 'sin(Pi/2)';

sin((1/2)*Pi)

G( expr1 );

1

G( eval(expr1,1) );

[sin, [`*`, 1/2, Pi]]

x := y;

y

expr2 := 'cos(x)';

cos(x)

G( expr2 );

[cos, y]

G( eval(expr2,1) );

[cos, x]

expr3 := 'sin(s*rand(0.0..1.0)())';

sin(s*(rand(0. .. 1.0))())

G( expr3 );

[sin, [`*`, .2342493224, s]]

G( eval(expr3,1) );

[sin, [`*`, s, [rand(0. .. 1.0)]]]

Download list_rep_eval01.mw

I've already mentioned automatic simplification, eg. 2*(x+y), q>=p, etc, which cannot be side-stepped with mere unevaluation quotes. In 2D Input mode the distinction is more clear between input syntax that gets treated prior to automatic simplification and the result of parsing to get an expression. Yet another parsing mechanism exists in InertForm for input represented as a string, eg, (for fun),

restart;

G := e -> `if`(e::atomic,e,[op(0,e),map(procname,[op(e)])[]]):

 

expr := InertForm:-Parse( "2*(x+y)" );

`%*`(2, `%+`(x, y))

lprint(expr);

2 %* (x %+ y)

G( expr );

[`%*`, 2, [`%+`, x, y]]

Download list_rep_InertForm01.mw

It's possible that none of these special cases are important to you, as you might have in mind only preconstructed formulas of expresions that involve arithmetic and "mathematical" function calls of fully evaluated expressions of type algebraic. But I don't yet know whether that's the case.

@janhardo I don't know whether the OP really wants to cover any expression, but you might be interested that there some things which act differently than your code expects:

restart;

 

toPrefix := e -> `if`(type(e,atomic), e,[op(0,e), seq(toPrefix(op(i,e)), i=1..nops(e))]):

Warning, (in toPrefix) `i` is implicitly declared local

 

table([f=a,q=s]);

table( [( f ) = a, ( q ) = s ] )

 

toPrefix( table([f=a,q=s]) );

Error, (in toPrefix) invalid input: toPrefix uses a 1st argument, e, which is missing

 

type( table([f=a,q=s]), atomic );

false

op( table([f=a,q=s]) );

[f = a, q = s]

nops( table([f=a,q=s]) );

2

op(1, table([f=a,q=s]) ); # NULL


Download table_vs_op_nops.mw 

It seems like a mistake to me, to have recursive code act on expressions for which the conditional (say, being not type atomic) is not always correctly supported by the ensuing tranformation (using op, nops, etc). Not only could you get an unexpected error (see example above), but in a worse case it might get into an untrappable infinite recursion.

@dharr For me the following works, without assumptions, in versions back to at least Maple 16.02 (2012).

> inttrans[laplace](FresnelS(t), t, p);

     (-1+LommelS2(1,1/2,1/2*p^2/Pi))/Pi


note. It's unclear why the OP tried putting an assumption on a, for an example not containing that name. It might help if the OP uploaded an actual worksheet.

@Roy Hughes 

You should upload (and attach) your worksheet using the green up-arrow in the menubar of the Mapleprimes Reply editor.

3 4 5 6 7 8 9 Last Page 5 of 607