acer

32939 Reputation

29 Badges

20 years, 147 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

This duplicates each frame three times (to slow down the exported .gif file).

It reduces the line thickness as n increases.

restart;

S:=CodeTools:-Usage(
  [seq(eval(subs(THICKNESS(0)=THICKNESS(max(0.01,1-1.2*n*0.02)),
                GraphTheory:-DrawGraph(GraphTheory:-CompleteGraph(n),showlabels=false)),
           _HOVERCONTENT=NULL)$1..3,
       n=3..40)]):

plots:-display(S,insequence=true);

Download graph_anim01.mw

 

 


Or, with labelled vertices, up to n=50, with just two repetitions per frame, and with lines getting thinner slightly more slowly.

restart;

S:=CodeTools:-Usage(
  [seq(eval(subs(THICKNESS(0)=THICKNESS(max(0.01,1-1.0*n*0.02)),
                GraphTheory:-DrawGraph(GraphTheory:-CompleteGraph(n))),
           _HOVERCONTENT=NULL)$1..2,
       n=3..50)]):

memory used=2.19GiB, alloc change=191.18MiB, cpu time=22.31s, real time=20.94s, gc time=2.53s

plots:-display(S,insequence=true);

Download graph_anim02.mw
 

Here's an example for the legend, and making the axes' labels and tickmark values bold.

Q1_3_ac.mw

I look forward to reading about what other bits you might have forgotten to mention.

The title option seems to have been broken in Maple 2023. It works ok in Maple 2022.2 and earlier.

I will submit a bug report.

The problem seems to be simply that a new outer Table (hidden borders on those inside it) was put around the assembly. And the title is still being put on the a Table that is just inside that. But the GUI only shows Table caption & title on the outermost of a collected of nested Tables. So the title's being attached to the wrong Table now, and not shown in consequence.

Here are two workarounds:

1) Use Explore's overview option instead (adjusting the padding, for the width),

Explore(plot(a*sin(b*t),t=0..10),
   parameters=[[a=1..20], [b=1..20] ],
  initialvalues=[a=6,b=5],placement='right',width=300,
  'overview'=cat("\n"," "$32,"My Explore"));

2) Utilize a (re-usable) procedure instead, which constructs the xml, fixes it up, and embeds it,

NExplore := proc(U::uneval,{title::string:=""}) local temp;
 temp:=XMLTools:-FromString(Explore(U,_rest,insert=false,returnxml=true));
 DocumentTools:-InsertContent(subsop(1=_XML_Table("captionalignment"="1",
   "title"=title,"captionposition"="0","drawtitle"="true",
   remove(type,[op([1,..],temp)],
          identical("captionalignment","title",
                    "captionposition","drawtitle")=anything)[]),temp));
 return NULL; end proc:

NExplore(plot(a*sin(b*t),t=0..10),
         parameters=[[a=1..20], [b=1..20]],
         initialvalues=[a=6,b=5], placement='right',
         width=300, title="My Explore");

explore_title_ex07.mw

Your Question's title asks, "why Explore gives error...", but it did not give an error. It gave 2 Warnings  and the exploration appears to run ok.

Internally, Explore makes a couple of evaluations of the expression, using right & left parameter end-points, to try and gauge what the maximal viewing range might be. It's only substituting the Slider value, not the TextArea value, when doing that.

If you don't want to be disable warnings you can avoid those messages by preventing the adaptive viewing mode (in which it tries to retain the largest `view` range found for any parameter values).

For example,

Explore(plot(a*sin(b*t),t=0..10),
   parameters=[              
        [a=1..20],
        [b,'controller' = 'textarea','label'="b" ]
        ],
  adaptview=false,
  initialvalues=[a=6,b=5],placement='right',width=300);

Notice how the vertical view changes dramatically as parameter `a` changes? It's somewhat awkward. That's what the (new in the past couple of releases) `adaptview=true` option is for, to get a more stable view experience.

Of course, you can force a widest view with,

Explore(plot(a*sin(b*t),t=0..10,view=-20..20),
   parameters=[              
        [a=1..20],
        [b,'controller' = 'textarea','label'="b" ]
        ],
  adaptview=false,
  initialvalues=[a=6,b=5],placement='right',width=300);

Yet another way to get rid of those two warning messages, while keeping the adaptiveview=true default, is to simply make it produce an empty plot (silently) when the parameter is non-numeric.

F := proc(ap,bp)
  if not ( ap::numeric and bp::numeric ) then
    return plot(axes=none); end if;
  plot(ap*sin(bp*t),t=0..10);
end proc:

Explore(F(a,b),
   parameters=[              
        [a=1..20],
        [b,'controller' = 'textarea','label'="b" ]
        ],
  initialvalues=[a=6,b=5],placement='right',width=300);

explore_slider_textarea_ex06.mw

As I explained in my Answer your Question yesterday, the slider controllers that Explore inserts are all Embedded Components Sliders. In fact, the very first URL link in my Answer yesterday is the very same link that you've cited here.

Consider this example, where the Slider snaps to only multiples of 10.

Explore( plot(a*sin(x), x=-3*Pi..3*Pi, gridlines),
         parameters=[ [a=0 .. 1000, majorticks=500,
                       minorticks=10, snaptoticks=true] ],
         initialvalues=[a=1000], width=500, placement=right );

nb. There is a minimal granularity that the GUI itself will allow, in terms of how it perceives small movements of a slider control. Ie, you can't make the slider be manually moved any arbitrarily small portion of the whole.

Also, the question about arbitrary values, entered manually, has come up before. (Prof. R.Lopez once asked me about that.) The code might be revised so that the (current, separate) Label component which shows the running Slider value is instead a TextArea component and that it serve double duty as both output (running value) and input (manual).

[edit] While they don't update each other, a Slider and a separate TextArea component can both be used in the same exploration to set the value of a common name in the "expression" (here, a function call F(a,aa) ).

F := module() local aval,ModuleApply;
  ModuleApply:=proc(a,aa) local use_a;
    if nargs=2 and aa::numeric and aval<>aa then
      aval:=aa; use_a:=aa;
    else use_a:=a;
    end if;
    plots:-display(plots:-textplot([5,30,typeset("a=",use_a)],color=blue),
                   plot(use_a*sin(x),x=-3*Pi..3*Pi,gridlines));
  end proc:
end module:

Explore(F(a,aa),
  parameters=[[a=0 .. 50, majorticks=10],
              [aa, controller=textarea, label="", width=3]],
  initialvalues=[a=50,aa=a],
  width=500, placement=right);

They each update the plotted expression (but not each other, as entry components).

explore_slider_ex05.mw

If you are using full-screen for the Maple GUI then you might try placement=right (or left) for the Sliders (optionally aligning them horizontally or vertically as you want). You can actually mix&match the placements. That might help keep your full plot visible while sliding. Of course for side-placementt you would not utilize your width=300 choice (which I personally feel is not going to be good for overall look&feel, in almost any event...).

I am not aware of a way to set the font family or size for the values markers shown on Sliders, a kind of Embedded Component (EC).

It can be mentioned that Table ECs don't have the fancy grid/etc layout or as many alignment choices that Maplets tables/cells do, and so fine placement within the assembly is cobbled together with a few invisible subtables. (It's a bit like trying to build a palace out of mud and sticks.) If I recall correctly the internal cell padding is already set to 0 for the internal layout of the Explore Tables. But you're right, it does look cludgy.

You can make the Sliders a bit longer, which can visually relieve a little bit of the awkwardness wrt the value markers.  Their length is constrained a bit by the internal layout (so they're limited by the overall width), but here's an example of the syntax: Explore_slider_width_ex01.mw

I'll also mention that the fonts in Embedded Components are quite different(!!) according to platform, including in terms of size as well as look/feel. Here's a Linux ubuntu screenshot, in which the Slider tickmark values look remarkably different than in the OP's screenshot (noticeably smaller, bolder, different font family, ie. noticeably different in all the key ways that fonts can be different). I don't know whether the differences are mostly a Java thing, a Maple GUI thing, or an OS thing.

I suspect that some of that vertical whitespace might be alleviated if the implementation were changed so that the hidden internal Table EC used for animation controls/etc were altogether not present when those controls are not used/shown. In EC, even an empty sub-Table with zero-padding adds bulk and white-space (again, unlike what can be done with Maplets, iirc). I could log a bug ticket for that.

How about a Matrix, using,

   <eval~(N, results) | eval~(tbo, results) | eval~(two, results)>

or,

   Matrix(map[2](eval, [N, tbo, two], convert(results, list)))

PrimesQuestion_ac.mw

Naturally, you could make a DataFrame from that Matrix, etc.

e := -tan((4*Pi)/9) + 4*sin((4*Pi)/9);

-tan((4/9)*Pi)+4*sin((4/9)*Pi)

radnormal(expand(convert(e,exp)));

-3^(1/2)


Download simp_one_way.mw

ps. Note that simplification-to-zero is quite often easier than is simplification to a particular form. Here, simplify(e+sqrt(3)) produces exact zero (0), directly, and that may well be related to why is can also handle it.

I agree with the OP that a strong (but potentially costly) simplifier would be useful some times. My oracle implementation of such gave me the incantation above which attained the result.

However, that particular sequence of commands makes reasonable sense here, and is something I'd try if left to my own devices: expanding, after conversion from trig to exp form, can often lead to a form containing things like -1 raised to rational powers (ie. powers of roots of -1), and radnormal or evala are natural ways to deal with simplifying such to nicer radicals.

For fun, (and noting that some special case handlers are also possible).

nb. The eval of calls by uneval-quoted `[]` is there to side-step inadventent arithmetic-on-lists(!) at intermediate replacement stages.

You can of course remove function or `<=` or any other type from the following code. I'm guessing at what you want covered.

restart;

H := ee -> eval(subsindets(ee, {`+`,`*`,`^`,`.`,
                                `=`,`<`,`<=`,function},
                           u -> '`[]`'(op(0,u),op(u)))):

 

H( (a+b*c)^2 );

[`^`, [`+`, [`*`, b, c], a], 2]

H( a*b(x)*c*d );

[`*`, a, [b, x], c, d]

H( sin(Pi*x*f(t))=Q );

[`=`, [sin, [`*`, Pi, x, [f, t]]], Q]

# automatic simplification by kernel
H( 2*(x+y) );
H( q >= p );

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

[`<=`, p, q]

H( Int(f(x),x=1..s) );

[Int, [f, x], [`=`, x, 1 .. s]]

H( b/c );

[`*`, b, [`^`, c, -1]]

# What other operators are you interested in?
lprint(whattype(1..s));

`..`

Download op_fun02.mw

Keep in mind that this is doing what's asked of it, working with the expression to which its input evaluates.  Eg. b/c vs the expression b*c^(-1), or q<=p vs the expression p<=q, etc.

It seems to me that having the transformer (3rd argument) of the subsindets call be something simple that appears like your simple original definition/requirement, is a natural kind of approach. I mean that in a hand-wavy kind of manner. If you start complicating the definition/requirement then writing a more complicated process might be order.

The description of what you want, and the details of the requirements, are key here. You've only provided a single example and a short description in your original Question. So extending that to other kinds of examples is dubious because of your thin specification.

Note that your Question's title mentions "of an expression", as if all expressions were to be covered. That doesn't explain how to deal with expressions that evaluate to something other than themselves. (Look at the operands of the result of a numtheory[cfrac] call...)

Also, your Question title just says listlist, as if your single example's output's list structure involving op(0,..) and op(...) were the only possible consequent form. But it's not, right? I mean you don't even have to flatten everything into a single sublist.

[edit] I'm a bit cautious about the recursion. The examples I've given can also be covered by,
    ee->eval(subsindets(ee,Not(atomic),u->'`[]`'(op(0,u),op(u))))
where the only difference is in replacing a specially curated choice of types by the blanket Not(atomic). It's not that I'm so worried about a runaway, as I am that you might not want so many things descended into.

Not everything that is not of type atomic is going to behave so nicely under op (see table example in my Reply to janhardo). So I would rather see a clear and careful collection of mentioned types, even if it's longer code.

There are some cases where the recursion by this particular subsindets approach will vary from that done by the recursive construction in the code given by janhardo. Eg, Vector([3,f(x)]) , but I'm not sure whether that matters to you. You didn't mention that you needed, say, to be able to reconstruct expressions from the resulting listlist.

Your full and precise goal is unclear.

I find that sometimes Maple does a bit better with simplifying in ln form, for arctrig.

restart;

kernelopts(version);

   Maple 2025.1, X86 64 LINUX, Jun 12 2025, Build ID 1932578

f:=subs(r=(sqrt(5)+1)/2,7*arctan(r)^2
        +2*arctan(r^3)^2-arctan(r^5)^2):

simplify(combine(convert(f,expln)));

   7/8*Pi^2

But even there, combine as intermediate step allowed it to work. (Sometimes, a factor call at just the right intermediate point helps...) It's not always obvious what intermediate form is simpler or will lead to further improvement.

The simplify command has to deal with alternate forms and paths, while avoiding getting caught in loops or inadvertantly trying something that can "blow up" (like some expand). It's heuristic, and often tweaked or improved. That's one reason why it's useful to report such weaknesses.

ps. Here we could convert to either ln or expln, to change the arctrig.

No this type check is not supposed to expand/simplify/collect-wrt-y. My claim is supported in a few places by documentation.

It's supported by parts of the 3rd bullet point of the help-page for topic type,linear . While discussing a different but closely situation it mentions, "[would otherwise require]...that the polynomial is expanded (collected) in x, and the type test is only syntactic". The upshot there is that this check does not expand or otherwise simplify, and is more syntactic in nature.

Also, degree(A,y) returns 2, while degree applied to collect(A,y) or expand(A) or simplify(A) returns 1. That kind of behaviour is explicitly documented on the degree help-page (later example, where "...normalization is necessary").

And the type,linear help-page explicitly defines its check as including a check that the degree is 1, in the 2nd bullet-point of its Description. The code also reflects that "definition":

showstat(`type/linear`);


`type/linear` := proc(f, x)
   1   if _npassed = 1 then
   2       type(f,polynom) and degree(f) = 1
       elif type(x,list) then
   3       type(f,linear({op(x)}))
       else
   4       type(f,polynom(anything,x)) and degree(f,x) = 1
       end if
end proc
 

Download type_linear.mw

Having said that, it'd be reasonable (I think) for the is command to be able to figure this out, mathematically rather than syntactically. And the type linear is also considered a property, in this context. However, in Maple 2024.2 the call is(A,linear(y)) unfortunately returns false, for your unexpanded A example. You might submit a bug report against that.

ps. quotes in italics above denote quotations from the documentation.

[edit] One might not always want to expand or simplify everything (eg. trigs/radicals/spec.-func./etc may be present). A practical alternative might be to do the check on collect(A,y) (like the last ?degree example). Or possibly frontend an expand.

How would you want to handle an example like, say, (y^2-1)/(y+1)+7 ?

Some examples,

A := (x+y+1)^2-(x+y-1)^2;

(x+y+1)^2-(x+y-1)^2

collect(A,y);

4*y+(x+1)^2-(x-1)^2

type(%,linear(y));

true

frontend(expand,[A]);

4*x+4*y

type(%,linear(y));

true

B := (y^2-1)/(y+1)+7;

(y^2-1)/(y+1)+7

collect(B,y);

(y^2-1)/(y+1)+7

type(%,linear(y));

false

frontend(expand,[B]);

y^2/(y+1)-1/(y+1)+7

type(%,linear(y));

false

simplify(B); # or normal(B); # loss of knowledge

y+6

type(%,linear(y));

true

Download type_lin_ex1.mw

I was able to get the following. If you are willing to accept a condition like x>0 for the odetest then it seems reasonable to try also passing that to dsolve.

The dsolve call happens to use the extra condition x<1, but the odetest check doesn't. (Without it, the dsolve call goes away for quite a while...)

Memory use is high, and sometimes it misbehaves, especially if doing further computations in the session. (Once I got a "bad id" error from the kernel.)

restart;

kernelopts(version);

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

ode:=-x*sqrt((1 - x)/(x + 1))*(x + 1)*arcsech(x)*diff(y(x), x)*exp(y(x)/arcsech(x) + exp(y(x)/arcsech(x))) - y(x)*exp(y(x)/arcsech(x) + exp(y(x)/arcsech(x))) + 2*x*sqrt((1 - x)/(x + 1))*(x + 1)*arcsech(x)^2 = 0;

-x*((1-x)/(x+1))^(1/2)*(x+1)*arcsech(x)*(diff(y(x), x))*exp(y(x)/arcsech(x)+exp(y(x)/arcsech(x)))-y(x)*exp(y(x)/arcsech(x)+exp(y(x)/arcsech(x)))+2*x*((1-x)/(x+1))^(1/2)*(x+1)*arcsech(x)^2 = 0

new := simplify(convert(ode,expln)) assuming x>0;

(ln(x)*(diff(y(x), x))*(-x^2+1)^(1/2)*x-ln((-x^2+1)^(1/2)+1)*(diff(y(x), x))*(-x^2+1)^(1/2)*x-y(x))*exp(((ln(x)-ln((-x^2+1)^(1/2)+1))*exp(y(x)/(-ln(x)+ln((-x^2+1)^(1/2)+1)))-y(x))/(ln(x)-ln((-x^2+1)^(1/2)+1)))+2*x*(-x^2+1)^(1/2)*(ln(x)-ln((-x^2+1)^(1/2)+1))^2 = 0

sol := CodeTools:-Usage( dsolve( new ) ) assuming x>0, x<1;

memory used=3.78GiB, alloc change=81.56MiB, cpu time=52.98s, real time=49.35s, gc time=11.25s

y(x) = -ln(ln(2*x-c__1))*ln(x)+ln(ln(2*x-c__1))*ln((-x^2+1)^(1/2)+1)

simplify(convert( odetest(sol,ode), expln)) assuming x>0;

0

Download de_hard02.mw

You could simply use Not(atomic), which imo is still pretty legible.

Or, if you'd like you can set that up as a new named type (and, optionally, put it in your init file if wanted).

restart;

 

TypeTools:-AddType( nonatomic, Not(atomic) );

 

type( sin, atomic );

true

type( sin(x)+cos(x), atomic );

false

type( sin(x)+cos(x), nonatomic );

true

Download AddType.mw

Is this the kind of thing you're after, making a distribution and random-variables based upon that PDF, and then, say, combining such RVs?

with(Statistics)

dz := proc (t) options operator, arrow; piecewise(t <= 0, 0, 0 < t and t < 2, -(3/80)*(-2+t)^3*(4+6*t+t^2), 2 <= t, 0) end proc

proc (t) options operator, arrow; piecewise(t <= 0, 0, 0 < t and t < 2, -(3/80)*(-2+t)^3*(4+6*t+t^2), 2 <= t, 0) end proc

int(dz(t), t = 0 .. 2)

1

zdist := Distribution(PDF = dz)

Z1 := RandomVariable(zdist)

Z2 := RandomVariable(zdist)

PDF(Z1, s)

piecewise(s <= 0, 0, 0 < s and s < 2, -(3/80)*(s-2)^3*(s^2+6*s+4), 2 <= s, 0)

z12pdf := PDF(Z1+Z2, s)

(1/1971200)*piecewise(s <= 0, 0, s <= 2, s^11-220*s^9+1320*s^8+7920*s^7-103488*s^6+147840*s^5+887040*s^4-2365440*s^3+2838528*s, s <= 4, -(s^4+28*s^3+228*s^2+536*s+80)*(-4+s)^7, 4 < s, 0)

int(z12pdf, s = -infinity .. infinity)

1

CDF(Z1+Z2, s)

piecewise(s <= 0, 0, s <= 2, (1/23654400)*s^12-(1/89600)*s^10+(1/13440)*s^9+(9/17920)*s^8-(3/400)*s^7+(1/80)*s^6+(9/100)*s^5-(3/10)*s^4+(18/25)*s^2, s <= 4, -(1/23654400)*s^12+(1/89600)*s^10-(1/13440)*s^9-(9/17920)*s^8+(3/400)*s^7-(1/40)*s^6-(9/175)*s^5+(3/5)*s^4-(176/105)*s^3+(288/175)*s^2+(256/385)*s-53/75, 4 < s, 1)

Mean(Z1+Z2)

36/35

Mean(Z1)

18/35

PDF(Z1+Z2, 3/2); evalf(%)

1781183979/4037017600

.4412128347

PDF(Z1+Z2, 3/2, numeric)

.4412128347

Download SphereFinal_ac.mw

The Help-page for topic procedure is describing technical aspects of a fundamental programming component of the Maple language, and the use of the word variable there is intentional jargon related to the Computer Science context of programming languages.

In contrast, in many mathematical contexts (for example, differential equations, integration, optimization, etc) the word variable has quite another set of connotations. And several other Maple's Help-pages reflect that, so as to be more broadly and readily understandable.

So, a word like "variable" can sometimes be used in a technical C.S. way when describing part of the Maple programming language, and can sometimes be used in a mathematical or general way.

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