acer

32313 Reputation

29 Badges

19 years, 311 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

One way is to have your deltaHat procedure return unevaluated if its arguments are not both numeric. That's an alternative to trying to use single right-ticks (a.k.a. uneval quotes) to prevent premature evaluation.

maple_primes_question_acc.mw

 

There is one case in which you specify the desired lower and upper values as well as their regular increments (for each direction, x and y). In this case the Matrix dimensions are dictated by those details.

Another case involves knowing the designated lower and upper values and then being given a Matrix whose dimensions are not specified up front by you. Here the Matrix entries might be interpreted as representing x-y values in the known ranges. In that case the increments follow from those details.

For example, matrixplot_ticks.mw

If you have some other scenario (eg. of what is given versus specified) then you should explain which parts are which and supply a concrete example.

 

The width thing can be solved a few ways, eg.

DocumentTools:-Tabulate( <header, dat>,
                         widthmode=pixels, width=330,
                         ':-fillcolor' = ((T, i, jj) -> `if`(i = 1, cyan, white))):

For the fonts, I'll have to wait until I get back in front of an actual computer (hopefully later tonight) to show how the result from Tabulate could be manipulated.

Or the entire Table could be constructed using DocumentTools:-Layout commands. That can become a chore for re-use, or more involved math examples, or repeated applications. I'll likely do your single example that way too.

There are actually two kinds of fonts and sizes in play, for strings and fortypeeset math equations. Handling each separately would be nicely more flexible. The numeric data is typeset like math (rendering nicely in upright Roman). Using text strings for floats otherwise can otherwise look poor. Both kinds of font size can be massaged after a call to Tabulate, I believe but must check later...

Having Tabulate accept additional cell-by-cell look&feel options (in a manner similar to how it allows for coloring) has been on my minor wishlist for a while now.

You wrote, "The proc needs to basically generate constansts to use to build an expression, similar to how dsolve uses _Cn".

That's fine, as a goal. But generating locals is quite likely going to be problematic for you, if you subsequently need to extract those names (eg. for the purpose of substitution). Utilizing indexed local names is not much better, and it's not really better at all if you would still need some additional mechanism to avoid collision or duplication or to robustly extract and re-use for manipulation.

Returning escaped locals is generally a poor technique which often requires more work and hoop-jumping after the fact.

If you are concernced that you should not use global names because they might collide with previously assigned names, then there's a convenient mechanism to avoid that. The following mechanism is utilized by other respectable Library procedures, and consists of concatenating a symbol with a nonnegint such that the result is a previously unassigned (non-colliding) global name.

For example,

restart;

# First, your approach with escaped locals.
foo:=proc(var::name)
 local A;
 return A[0]+A[1]*var
end proc:
ans1 := foo(x);

           ans1 := x A[1] + A[0]

# The following doesn't work, because we don't have
# the local version of the name A, to pass to `type`.

indets(ans1, suffixed(A, nonnegint));

                    {}

# Now, using generated, noncolliding global names.
bar:=proc(var::name)
 return `tools/genglobal`(':-A')
        + `tools/genglobal`(':-A')*var;
end proc:

We can even assign safely to global base name A, and still get a useful process.


A := 13:
ans2 := bar(x);

           ans2 := A1 x + A0

indets(ans2, suffixed(':-A', nonnegint));

               {A0, A1}

bar(x);

               A3 x + A2

bar(x);

               A5 x + A4

indets(%, suffixed(':-A', nonnegint));

              {A4, A5}

Let's suppose that you were writing your own symbolic ordinary differential equations solver. In that situation I think that you generally would be better off with generated non-colliding global names (say, for constants of integration, or arbitrary constants) than with indexed references to escaped locals.

Your problematic call to select is selecting individually from the operands of a single product, not a sum of products.

Note that the empty product is 1 (akin to how the empty sum is 0). Since none of the individually tested operands in the product expression satisfy the whole type query the select result is the empty product.

You seem to have the mistaken impression that the single expression (a product) is merely one term in a sum (of one term only). But that is incorrect.

This is not the first time that you've been in this particular kind of muddle in the past few weeks.

In one recent Question of yours on the very same topic I showed and mentioned that a preliminary test may be needed, ie. in this case testing whether the the overall expression is of type `+` before calling select on it as if it were a sum of terms (eg. sum of products).

Using Maple 2020.2,

simplify(rationalize(f(-2)));

           1  (1/2)   1
           - 5      + -
           2          2

evala(g(-2));

           1  (1/2)   1
         - - 5      + -
           2          2

evala(h(-2));

                1

Here is one way, which you should be able to adjust as wanted.

You had only two values in the lists for labels and labeldirections, but 3D plots require three. I fixed that.

Note that the size option is not available in Maple 2019 for 3D plots. I put in a workaround.

Help_3D_ac.mw

With M=0.2 fixed,

Or with M=0..10 as the second plotting variable,

(The above approach could be figured out by reading the Help page for topic textplot3d.)

You are probably aware that in general quintics are not solvable in terms of radicals. I don't see any avenue to an explicit exact solution here. But a numeric result can be obtained straightforwardly.

restart;

eqn := 64/19683*t^9 - 16/729*t^7 = (-t + sqrt(t^2 - 4))/2:

S := solve({eqn, t>2}, t, explicit):

    {t = 1/2*9^(1/2)*2^(1/2)
         *RootOf(4*_Z^5-2*_Z^4-2*_Z^3-4*_Z^2-_Z-1,index = 1)^(1/2)}

evalf(S);

               {t = 2.557990173}

fsolve(eqn, t=2..infinity);

                 2.557990174

Are you asking for a formal proof or demonstration that this quintic might not be solvable in terms of radicals? If so, what is your math background?

Would you be satisfied by seeing messages about what the internal routines underneath solve are ascertaining?

restart;
eqn := 64/19683*t^9 - 16/729*t^7 = (-t + sqrt(t^2 - 4))/2:
infolevel[solve]:=6;
S := solve({eqn, t>2}, t, explicit):

restart;
infolevel[solve]:=6;
solve(4*tt^5 - 2*tt^4 - 2*tt^3 - 4*tt^2 - tt - 1, tt, explicit);

I usually find it more convenient to use assuming rather than assume. It might also help you avoid this particular difficulty.

pi_filter_osc_anal_ac.mw

expr := alpha[3, 5]*xi[1]*xi[8] + alpha[3, 5]*xi[4]*xi[5] + alpha[3, 3]:

indets(expr, 'specindex(alpha)');

           {alpha[3, 3], alpha[3, 5]}

indets(expr, 'specindex(posint,alpha)');

           {alpha[3, 3], alpha[3, 5]}

You can find this (and several other related or useful structured types) on the Help page with Topic type,structure .

It's not entirely clear to me, from the implicitplot's Help page's Options section, why this should be so. But passing the adaptranges=false option produces this constrained red curve.

restart;
kernelopts(version);

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

plots:-display(
  plots:-implicitplot(-x^2 + y, x = 0 .. 1, y = 0 .. 1-x^2,
                      adaptranges=false, color=red),
  plot(1-x^2, x=0..2, y=0..2, color=blue) );

As mmcdara mentioned, it worked as you expected in Maple 2015.2. But not in 2016.2 and onwards, it seems. I will submit a report; its maintainer will know whether its a behavioral bug, or needs clarification in the Help.

The type &* can check for a specific number of multiplicands, of specified types, in a specified order.

The type `*` checks merely that all multiplicands are of the given type, with no regard to number, no guarantee of presence, and no guarantee or order. But the given type can be specified as a structured type, and that includes the possibility of using {} or Or to denote alternative matching types. If no type is specified then it's just a check that the expression is a product of any two or more terms.

The first of the above, &*, might sound useful but in practice can present difficulties because the terms in a product may get re-ordered (on account of unification of expressions, as represented in the kernel/engine). I showed a way to check for a specific number of specified types, appearing in any order, in another very recent Question by you. There are a few other related queries possible, that can be programmed.

The second of the above, `*`, is handy for checking either that an expression is just a product, or that all its multiplicands can only be of some given set of types. If you supply it with a set of possible types then in general there's no guarantee that each of those types are actually represented at all by any multiplicand present in the expression, or represented by distinct multiplicands. And so in general it's not a mechanism, alone, for precise pattern matching. It's great for checking that multiplicands can only be from some specified class -- which is a very common need even if it may not be your current need.

I use type `*` a great deal. I'd be hard pressed to remember the last time I used type &*, other than to address some of your recent Questions on type checking.

[edit] I don't want to lead you to incorrect conclusions about type &*. But there are some kinds of terms whose order within a product is guaranteed. For the expression, say,  3*x*y*z the rational coefficient will appear first. There are a small number of such rules, but I am really not sure whether figuring out and relying on those in some complicated mechanism might be beneficial for you.

You've only provided a simple, restricted, single example and then asked for a generalization about which approach is more suitable. (Your example is restricted in at least the sense that it has exactly two multiplicands, with multiplicands of distinct types, with at least one multiplicand being special wrt ordering.) Your example is so restricted that it satisfies both type checks under discussion. If you want a general rule for programming then consider your widest class of possible example, not the narrowest.

You asked about a "rule of thumb". In various situations, one of the key things is to figure out whether you're trying to 1) restrict which types might be present, or 2) ascertain whether some target types are definitely present. Those are quite different kinds of goal. The type `*` is often very useful for the former. For 2) I find it often productive to augment type `*` with tight queries that delineate the relevent cases -- where useful helper tools can include type satisfies, membertype, etc.

Your example does not adequately illustrate the underlying considerations.

In particular your example fails to illustrate that expansion (of at least some sort) may be required in order to discern what trig cancellations and simplifications are possible.

Consider this conceptually minor tweak to your example, and see how lack of expansion of the polynomial terms messes up some possible cancellation of terms.

restart;

ee := (cos(x)^2+sin(x)^2)+5
      +(1+x+x^2+x^3)*(sin(x)^2)*exp(x)
      +(x + 1)*(x^2 + 1)*(cos(x)^2)*exp(x):

simplify(ee, trig);

                              / 2    \       
                  6 + (x + 1) \x  + 1/ exp(x)

thaw(simplify(subsindets[flat](ee,satisfies(Z->type(Z,polynom(integer, x))),(freeze))));

        //        / 2    \    3    2        \       2    3    2    
    6 + \\(x + 1) \x  + 1/ - x  - x  - x - 1/ cos(x)  + x  + x  + x
    
      \       
       + 1/ exp(x)

Some other problematic examples may be readily found.

I believe that it's also possible to find examples for which some possible trig cancellations will not be found (due to other lack of expansion).

[edit] Of course there are lots of alternative ways to produce that target result for the given example. Eg,

expr:= (cos(x)^2+sin(x)^2)+5+(1+x+x^2+x^3)*(cos(x)^2+sin(x)^2)*exp(x):
collect(expr, exp, simplify);

                      / 3    2        \       
                  6 + \x  + x  + x + 1/ exp(x)

collect(expr, exp,
        u->simplify(u,trig,applysimplifysize=false));

                      / 3    2        \       
                  6 + \x  + x  + x + 1/ exp(x)

I think that is quite beside the main point, since there are many other examples for which the original question applies but which will not be handled by such any one such simple technique (including that given by Kitonum in his Answer).

I interpret the original question as being about how (arithmetic) expansion or factoring might be avoided while allowing for the trig-specific simplifications. My answer is summarized by saying that such expansion of the relevant subexpressions or coefficients is (at the very least temporarily) generally necessary in order to ascertain which trig subexpressions might cancel or simplify.

Speculative expansion of subexpressions (examining which might or might not help, say) is possible but can be quite expensive.

The amount of clean-up simplification is another consideration. I might mention this avenue of computation:

simplify(expr, trig, applysimplifysize=false);

                     3           2                    
         6 + exp(x) x  + exp(x) x  + exp(x) x + exp(x)

The values specified by the size option actually dictate the dimensions of that frame, ie. the inlined plotting window. They don't dictate the lengths of the axes, or the visible extent of the plot features.

But your goal seems clear: you want the visible entent of the plotted feature to agree, between plots, as much as possible. And currently you are seeing a mismatch in the horizontal extent at which some of your plots are rendered.

You won't be able to utilize the size option, alone, to fix your problem, because as mentioned that specifies the dimension of the plotting window/frame. Those dimensions can be made to agree, and that sees like a good start. But the visible extent within those similarly-size frames is the key issue, and for your examples the plots do not render to the same extent up to the common frame boundary.

The bad new is that there seems to be a quirk in the plot renderer, that occurs whenever certain POLYGONS' substructures with surface style have a boundary point too close the axis' end points (with default, axes=normal look). Specifically, if certain POLYGONS' substructure is too close then the GUI will not render that polygon right up to the axis end-point, but instead will clip it upon rendering. In that situation it will also no longer render the background or some other plot features up to the axis end point. That's a shame. Your filled inequal plot contains such POLYGONS, for the filled areas. Internally inequal uses the surface style to produce an agglomeration of polygons that are rendered without borders, giving the effect of a filled region. The occurrence of the problem also seems to depend on relative scale.

I attach a worksheet that hopefully illustratess what I mean in the description above.

plot_scratch.mw

I can tell you that the problem is not fixed by forcing a "default" view, or removing the VIEW substructure, or labels. The GUI simply will not render certain filled polygons right up to the extent of the some kinds of displayed axes (in axes=normal configuration).

The problem might be due to a reluctance of the GUI to render a style=surface POLYGONS structure too close to outermost major tickmarks. I am not sure.

Also, the problem is not apparent for axes=box. The problem occurs for axes=normal, which is how your examples looked by default. With axes=box then the axes-boxes all agree. But you won't be able to get all manner of 2D plots to look similarly rendered this way, because different plots can have very different value widths for the y-tickmarks and y-axis label. With axes=box you can only get very close extent in the rendered dimensions (ie. same closeness to plotting frame/window) if you forcibly remove all axes labels and tickmarks. That might be unacceptable for your work. plot_scratch2.mw

If I think of anything useful I'll follow up here, but so far all I'm aware of are kuldgy techniques that can work on a plot-by-plot basis. And you seem to need a general approach.

The problem is a conflict between the type specification of ::positive that you put on func's first procedural parameter, and the fact that you've called func(x) with symbolic, non-numeric name x.

You'd get the same error message if you just called func(x) at the top-level, rather than as first argument to the Secant command.

The easiest solution is to remove that ::positive parameter type-spec on the func procedure. That parameter type-spec doesn't help here -- it just gets in the way.

An alternative is to use single-right-tick uneval quotes, to prevent func(x) from evaluating until such time that x is actually given a numeric value under the caller (here, the Secant command).

Also, there's no benefit to wrapping your operator f inside another operator func. (That's just a waste of time.) So I will use just f directly. But for your benefit I will show how the (unhelpful) ::positive parameter type-spec can be dealt with, because you asked.

By the way, the stock Maple command for numeric root-finding is fsolve. You can use that command with either its operator form or expression-form calling sequence.

restart;

f := (x::positive) -> x^3 - 7*x^2 + 14*x - 6:

Student:-NumericalAnalysis:-Secant( f(x), x=[2.7,3.2], tolerance=10^(-2) );
Error, invalid input: f expects its 1st argument, x, to be of type positive, but received x

Student:-NumericalAnalysis:-Secant( 'f'(x), x=[2.7,3.2], tolerance=10^(-2) );

               3.005775858

fsolve( f, 2.7 .. 3.2 );

               3.000000000

fsolve( 'f'(x), x=2.7 .. 3.2 );

               3.000000000

I understand that your homework assignment might have literally said that you should write a procedure. Note that the operator f above is actually a procedure. It just has some special options that make it print with that neat arrow.

I'm curious, are you sure that your homework assignment isn't asking you to write a procedure that implements some numeric root-finding algorithm (secant method, bisection, etc), rather than merely use a Maple command that has already implemented it?

First 84 85 86 87 88 89 90 Last Page 86 of 336