acer

32405 Reputation

29 Badges

19 years, 351 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

This is not specific to the name Digits.

That particular abbreviated syntax for entering floats (with the "e") requires a literal number for the exponent, not a name (whose value might be an integer). And that is all.

I realize that you are aware of several alternatives.

Your previous Question was about acting on a "whole expression" that was a sum of terms.

If this new Question thread relates to that (a sum of terms) as the another kind of relevant "whole expression" then that fact may dictate a course of action.

Here is a common approach to a related and somewhat common situation. (I cannot tell if it truly represents your situation, because you haven't fully described it.)

if type(expr, `+`) then
  select(type, expr, mytype);
elif type(expr, mytype) then
  expr;
else
  # Choose some appropriate
  # and meaningful fallback. Eg,
  0;
end if

You might wish to interchange positions of those first two conditions/actions.

But in general it may be quite innappropriate to make that `select` call (as Joe did,  following your cue) without knowing or checking that `expr` is something over which you'd want that action taken.

You might validly want `select` to act over the operands of `expr`, if it is a sum of terms. But otherwise that action might be inappropriate.

Ie. if `expr` were some other kind of multi-argument function-call then calling `select` on it might well produce a nonsensical result.

Just because expr is not of type mytype doesn't mean that it must be something (eg. a sum of terms) to which `select` can/should be appropriately applied. It could be a radical, or a special-function or trig call, etc. What's the sense in calling `select` on those beasts here, as fallback clause?

One problem here is that you are suppressing the output of the lines which assign to expr_1..expr_6. That prevents you from visualizing the ordering of multiplicands in the resulting product terms, which is part of the explanation.

The product subterms like, say, sin(x)*(1+x+x^2) are uniquified in memory. For efficiency Maple only stores one copy of this product (DAG). Its first creation specifies the ordering with which later instances are uniquified. If you subsequently enter (1+x+x^2)*sin(x) then that will be a reference to the (earlier) stored instance.

restart;

3+sin(x)*(1+x+x^2);

                       / 2        \
            3 + sin(x) \x  + x + 1/

3+(1+x+x^2)*sin(x);

                       / 2        \
            3 + sin(x) \x  + x + 1/

Another part of the problem is your particular choice of type. Compare with the following, which is not affected by the multiplicative ordering. Below, I force both orderings, and both succeed here.

restart;

3+sin(x)*(1+x+x^2);

                       / 2        \
            3 + sin(x) \x  + x + 1/

expr:=3+(1+x+x^2)*sin(x);

                       / 2        \
            3 + sin(x) \x  + x + 1/

select(type, expr,
       '`*`'({polynom(And(algebraic,
                          satisfies(u -> not has(u, I))),x),
              specfunc('sin')}));

                     / 2        \
              sin(x) \x  + x + 1/

restart;

expr:=3+(1+x+x^2)*sin(x);

                / 2        \       
            3 + \x  + x + 1/ sin(x)

select(type, expr,
       '`*`'({polynom(And(algebraic,
                          satisfies(u -> not has(u, I))),x),
              specfunc('sin')}));

              / 2        \       
              \x  + x + 1/ sin(x)

note: I didn't change the quoting within your inner types. It's not necessary to uneval-quote sin, as it's a protected name. But quoting specfunc may be prudent.

Perhaps another way to phrase it might be: it's not appropriate to use a noncommutative product type specification (in which ordering of multiplicands is specified) for a test on products in which commuting of multiplicands may occur.

[edit] There are related examples which may be of interest. The alternative I gave above does not guarantee that all the given types will appear in the products that are accepted, for more general examples.

Here's another example, and two other alternatives (which also allow for different orderings). The predicate in the last call to select allows only those products which contain exactly one multiplicand for each of the given types. And the middle select call requires that all the given types are represented.

restart;

3+sin(x)*x^2+x^4*sin(s)*cos(s)+x^6*cos(t):
expr_1:=3+x^2*sin(x)+sin(s)*cos(s)*x^4+cos(t)*x^6;

              2    4                  6       
  3 + sin(x) x  + x  sin(s) cos(s) + x  cos(t)

T := {polynom(And(algebraic,satisfies(u->not has(u, I))),x),
      specfunc('sin')}:

select(type, expr_1,'`*`'(T));

            2    4                  6       
    sin(x) x  + x  sin(s) cos(s) + x  cos(t)

select(u -> u::`*`
            and andmap(membertype,T,[op(u)]),
       expr_1);

                  2    4              
          sin(x) x  + x  sin(s) cos(s)

select(u -> u::`*` and nops(u)=nops(T)
            and andmap(membertype,T,[op(u)]),
       expr_1);

                           2
                   sin(x) x 

It's not clear from your very simple example whether in general your other examples of this task would each have their specified types cover disjoint classes of expression, or whether you are hoping to establish a 1-1 correspondence between the expressions (ie. multiplicands in a product) and the list/set of specified types. You should clarify that, though perhaps you consider that mention of pattern-matching in other related recent Questions by you might make it obvious(?).

As the error message indicates, the conditional check (of the `while` clause of the do-loop) cannot be tested if fs and de have not been assigned numeric values.

And, indeed, the very first iteration has that problem.

You could assign f(x0) to fs, and any concrete value greater than tol to de, just before beginning that while-do-loop.

Alternatively, you could use `until` to check at the end of the iteration, instead of using `while` to check at the start of each iteration.

I'll let you give it a shot, since it's likely homework. Let us know if you have further trouble.

If you right-click on a Slider then one of the choices in the drop-menu is "Edit Value Changed Code".

That is the code that will be executed whenever the Slider's position is changed manually, by sliding it with the mouse.

In the following attachment, I have made this be that code.

a := Pi/DocumentTools:-GetProperty("Slider0", ':-value');

DocumentTools:-SetProperty("TextArea0", ':-value', a);

When the mouse slider is moved manually then this code is executed. It does two things: it assigns Pi/(the new value) to the name a, and it writes the assigned value of a to another component that I'd inserted (a TextArea component).

CreatingSlider_ac_ac.mw

You can adjust that code as you see fit. You could have it assign to a, but not write to the TextArea component. Or you could use the value to write to the TextArea component without assigning to (or using) a separate variable such as a.

Another useful approach can be to have the component's action-code be a call to a user-defined procedure which you set up outside the component. But for now, perhaps it's best to focus on getting the basics of the control flow working.

note. I suggest that you refer to the identity of components as strings (here, "Slider0" and "TextArea0") as strings using double-quotes, not as names. I also prefer GetProperty/SetProperty over Do.

remark: in your original attachment you had  sin*(a) which is a multiplication, not a call to the sin command. I suppose that is an accidental syntax mistake.

You could look (again) at this prior Post.

note. I don't really understand why some people seem to prefer a graph that might not encapsulate at least as much detail as the dismantle command provides.

I also don't think that the more convenient layout for such a graph is one which splits each level horizontally.

restart;

ig := L*(1 - a^3/r^3)^(-1/2)/r:

eq := u = 1 - a^3/r^3:
IntegrationTools:-Change(Int(ig, r), eq, u);

      Int(-1/3*L/u^(1/2)/(u-1),u)

sol := eval(value(%), eq);

    2/3*L*arctanh((1-a^3/r^3)^(1/2))

diff(sol, r) - ig;

                    0

I used what seemed a reasonable candidate for a change of variables. I get the same final result (with different intermediates, of course) using u=a^3/r^3 or u=1/r^3 instead.

This seems to be a consequence of the 2D output typesetting in extended mode.

It doesn't happen for me if I first set (in a separate execution group from a restart),

   interface(typesetting=standard):

If you have a procedure that evaluates v__c(t) for any given numeric value of t, then there is no need for using point-probes (and I think that doing so in that case would be a relatively poorer approach, on several different grounds).

note: even in the less common scenario that the function for v__c(t) is not explicitly available (and, say, the original curve is obtained using the implicitplot command or similar), numeric rootfinding should still be possible for each known t-value.

Here is an example, using an invented operator for v__c(t).

plotting-ilines.mw

If you have only an expression for v__c, rather than an operator (procedure) then show us, and the adjustment should be straightforward.

The following considerations might be obvious to some people, but I'll spell them out anyway. I consider these advantages for someone learning Maple:
1) The solution is programmatic. After addition of additional t-value points, or a change to the definition of the plotted "function", the plotting code can be re-executed directly.
2) The various pieces (text-plots, dashed lines, etc) are on separate code lines for clarity, and each could be easily removed, adjusted, etc.

Shorter solutions are possible, although very terse approaches (eg. via more functional programming) are less legible and more difficult for the beginner to adjust.

I didn't put in cross-symbols at the intersection points. That would be a straightforward addition.

You mentioned linear regression in a few places. Perhaps you want something like these:

regr_3d2d.mw

pts:= Matrix([[19.8,12, 1.62],[24.7,14, 1.2],
                   [26, 16, 1.25],[35.1,20, 0.84],
                   [37.8,20.83,0.74],[10.8,9, 3.98],
                   [16.1,12, 2.46],[38.3,18, 0.52],
                   [24.5,16, 1.42],[15.8,11, 2.35],
                   [28.2,17.8, 1.19],[56.8,27, 0.37],
                   [25.4,17, 1.34],[29.3,18.1,1.12]]):
F3d:=Statistics:-LinearFit(a*x+b*y, pts, [x,y]);

       F3d := -0.210960256326733 x + 0.440339719466169 y

plots:-display(
  plots:-pointplot3d(pts,color=red,
                     symbol=solidsphere,symbolsize=12),
  plot3d(F3d,
         x=min(pts[..,1])..max(pts[..,1]),
         y=min(pts[..,2])..max(pts[..,2]),
         color=gray,style=surface,transparency=0.1),
  labels=[x,y,""], lightmodel=none, axes=box);

F2d:=Statistics:-LinearFit(a*x, pts[..,[1,2]], x);

                   F2d := 0.560023063311019 x

plots:-display(
  plot(pts[..,[1,2]],style=point),
  plot(F2d,
       x=min(pts[..,1])..max(pts[..,1])),
  labels=[x,y], axes=box);

 

For the explicit solution, my Maple 2021.1 can get the following,

restart;
kernelopts(version);

   Maple 2021.1, X86 64 LINUX, May 19 2021, Build ID 1539851

ode := diff(y(x),x)-y(x) = x*y(x)^(1/2):
ic := y(0)=4:
maple_sol_e := dsolve([ode,ic], 'explicit'):

odetest(factor(maple_sol_e), [ode,ic]) assuming real;

               [0, 0]

For the implicit solution, I wonder whether odetest might be utilized twice (bootstrapped)!?.

Your code is set up to only ever execute the Bez:-Click procedure, upon clicking. And that procedure is only set up to add the current clicked point.

What you want, I think, is to have the Click code call procedures which appropriately add or remove a point, according to the state of the checkboxes. You  can do that in two ways, as conditonal code in the Click procedure:
1) have Click examine the values of the checkboxes, and dispatch according to procedures which add/remove the current clicked point.
2) have Click examine a module local which stores the current mode or operation (adding, or removing), and dispatch accordingly.

Also, if you select/toggle-on either of the checkboxes then you'd want the other unselected/toggled-off. Instead of putting in code to manage all that, it's simpler to replace the two checkboxes with a pair of radio-buttons in the same "group". That way the GUI automagically toggles the other off when either is toggled on. (That's the main distinction of of radio buttons versus checkboxes.)

The modification in the attechment takes route 1), and examines the values of the radio buttons in the conditonal check. The way I have it, there is no action code directly inside the radio buttons.

An alternative to the conditional checks on the values of the radio buttons is to have a new module local which stores the running state/purpose, and do the conditional checks on that local instead. Then you could have the action code of those radio buttons set the value of that local appropriately. I did not do it that way, but both ways can work.

Also, I changed the reset checkbox into a button.

I also added a line which (I hope) will make the Plot1 component be set into a state where mouse manipulation actions are click/click-drag instead of point-probe/etc. Without that your original worksheet was re-opening for me with the manipulator in the wrong state.

sketch_ac.mw

(I used Maple 2015.2 for the changes.)

[edit] If your collection of checkboxes/radiobuttons has only two members, reflecting a single boolean condition, than another alternative is to use just a single toggle-button. (You could even toggle its caption between "add" and "remove".)

Maple is a case-sensitive language, and the command you were trying to utilize is spelled with, all in lowercase.

You accidentally used the capitalized name With.

Note that you can also call the GetProperty command by its fully qualified name. See attached.

CreatingSlider_ac.mw

Most "new" user-level Library commands (created since around 2000) have so-called Camel case spelling, but there are many much older commands that have purely lowercase spelling.

You haven't shown us how you were testing a pair of expressions against each other.

If you were using evalb then you should read its Help page carefully.

Here are a couple of approaches,

restart;

expr1 := -a*b + a*c:
expr2 := a*(c-b):

is(expr1-expr2=0);

           true

evalb(simplify(expr1-expr2=0));

           true

eq1 := expr1 = expr2;

    eq1 := -a b + a c = a (c - b)

is((rhs-lhs)(eq1)=0);

           true

evalb(simplify((rhs-lhs)(eq1))=0);

           true

# note the following

evalb(expr1=expr2);

           false

evalb(eq1);

           false

If your were doing something else, or had additional examples, then you should show that here explicitly.

This is not really satisfactory, but I'll mention it nonetheless,

restart;
ode:=diff(y(x),x) = 2*(2*y(x)-x)/(x+y(x)):
ic:=y(0)=2:

combine(dsolve([ode,ic],'implicit')) assuming x>0, y(x)>2*x;

     ln(2*(y(x)-x)^2/(y(x)-2*x)^3) = 0

combine(dsolve([ode,ic],'implicit'), symbolic) assuming x>0;

     ln(2*(y(x)-x)^2/(y(x)-2*x)^3) = 0
First 86 87 88 89 90 91 92 Last Page 88 of 336