acer

32385 Reputation

29 Badges

19 years, 335 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

Perhaps you want to do something more like this?

I am guessing here. I have moved the end if, and use sum1[n-1] on the right-hand side of that problematic assignment, and initialize sum1[-11] to zero.

new_ac.mw

Here is one way, using algsubs instead of subs:

restart;
eq_5 := x = -(K_i*Zs - Z_AB - Zs)/(K_i*Z_AB);

                              K_i Zs - Z_AB - Zs
                eq_5 := x = - ------------------
                                   K_i Z_AB     

eq_5_m5 := x = expand(rhs(eq_5));

                               Zs     1       Zs   
             eq_5_m5 := x = - ---- + --- + --------
                              Z_AB   K_i   K_i Z_AB

expand(algsubs(Zs/Z_AB = K_S, rhs(eq_5_m5 )));

                                1    K_S
                        -K_S + --- + ---
                               K_i   K_i

Q20210103_ac.mw

[edit] It's worth noting that the expression Zs/Z_AB is not structurally present as a subexpression of Zs/(K_i*Z_AB) as stored in memory by the Maple engine. Yes, the former divides nicely into the latter, but the former is not structurally present in the latter. That's why your attempt using subs failed. The subs command does syntactic rather than "algebraic" substitution. (It's a frequent mistake, to try and use subs for all manner of mathematical substitutions.) See the Help page for algsubs, for some more examples.

Btw, your example could also be handled by simplify-with-side-relations, eg.

expand(simplify( rhs(eq_5_m5 ), {Zs/Z_AB = K_S}));

What you are encountering is an artefact of the printing of a Vector (or Matrix).

If you programatically access the entries of u then you will get results containing the current running value of the m parameter. Hence, if that is what you mean by "automating calculuations" then you may be good to go. This works because the entries are fully evaluated upon access.

If you have a program which needs to do a very large number of such accesses of a Vector/Matrix which contains such a parameter (subsequently assigned a new value) then you can do the full evaluations altogether, up front, which can be more efficient. The rtable_eval command provides this functionality.

This also happens to allow printing to display as you wanted, since the ensuing Vector (newly created by the rtable_eval command) doesn't contain the unevaluated name of the parameter.

Pay attention also to the fact that once you instantiate the Vector at a given value of the parameter then such new Vectors don't reflect those new values. But the original u Vector does.

restart;

u := <-2+m,3+m>;


                       [-2 + m]
                  u := [      ]
                       [3 + m ]

m := 5;

                       m := 5

u;

                      [-2 + m]
                      [      ]
                      [3 + m ]


u[1], u[2];

                        3, 8

T := rtable_eval(u);


                          [3]
                     T := [ ]
                          [8]

T;

                        [3]
                        [ ]
                        [8]

# Notice the name of the parameter
lprint(u);
Vector[column](2,{1 = -2+m, 2 = 3+m},datatype = anything,storage = rectangular,
order = Fortran_order,shape = [])

# Notice the absence of the name of the parameter
lprint(T);
Vector[column](2,{1 = 3, 2 = 8},datatype = anything,storage = rectangular,order
= Fortran_order,shape = [])

m := 17;

                      m := 17

u[1], u[2];

                      15, 20

T[1], T[2];

                       3, 8

Vector_rtable_eval.mw

Another way to produce a new Vector instantiated at the current value of the parameter is to map the eval command across it. Eg, map(eval, u) .

The behaviour you encountered in the printing of a Vector (or Matrix, or Array) is due to efficiency reasons: that structure is not fully evaluated entry-by-entry (and no full copy is made) each time it gets passed in a procedure call -- including passage to the printing procedures.

You could increase working precision. One root is so close to 1.0 that default Digits=10 is inadequate.

Digits:=16:

ans := fsolve(r2,ksi);

                   ans := 0.9999999999994157

eval((rhs-lhs)(r2), ksi=ans);

                                       -8
                       1.37357117458 10  

You could also make Digits greater still, and obtain higher accuracy.

II.01_ac.mw

You can construct a procedure which returns unevaluated when called with nonnumeric arguments returns unevaluated. You can then pass that around like an expression (if you want).

In the attached worksheet, I construct a procedure F_yX with parameters y and X. It computes the numeric integral for x=0..X and after substituting the given value of y.

You can construct other, similar, procedures, according to whether you want to compute a double integral (y=0..Y, x=0..X, or whatever), or a single integral y=0..Y for a fixed x value. There are other variants of this approach, depending on what you want as integration bounds, etc.

You haven't properly explained how you intend on using the result, which makes it difficult to cover all possibilities in an answer.

If this is not sufficient then you should explain properly what you mean when you write, "...i need an expression for v to use another place, i do need required its numeric value".

Integration_Help_ac.mw

By the way, it might be the case that exact symbolic integration is possible (or numeric integration is more stable) if you could manipulate or "simplify" the integral before all those coefficients appear as floats. This may be to complicated for you (...we've been here before...).

Your expressions contain some terms raised to the power 1.0 (a float) which may interfere with a straightforward exact symbolic solution. I edited, and removed that effect.

The oldest version I have onhand is Maple 16, and you could try the attached worksheet in your older Maple 11.

I also changed names gamma to lgamma and D to lD, just to avoid (unlikely) collision with the special names that already have meaning to Maple.

E_ac.mw

The explicit solution attained contained this,

[X = sqrt(2)*sqrt(X1), Y = (2*I)*sqrt(2)/sqrt(Pi)]

The inverse of StringTools:-Encode is StringTools:-Decode (as Tom and the OP also mentioned). The inverse of sprintf is sscanf (as vv also mentioned).

f := sqrt(x);    # assumed to be unknown

                                (1/2)
                          f := x     

u  := sprintf("%Zm", f);  # "process" P1

                      u := "*$%"xG#"""""#"

s  := StringTools:-Encode(u,':-base64');  # "process" P2

                  s := "KiQlInhHIyIiIiIiIw=="

# The "inverse" of P2 is
v := StringTools:-Decode( s, 'encoding' = ':-base64' );

                      v := "*$%"xG#"""""#"

sscanf(v, "%m")[];

                              (1/2)
                             x     

The reason that "%Zm" is used in the sprintf formatting string is a backwards compatibility issue. If I recall correctly, when the DocumentTools:-Layout:-Equation procedure was developed the GUI dealt with an older "dotm" (a.k.a. ".m") encoding with some subtle differences compared with how the kernel (and sprintf) deals with some newer polynomial DAG structures. Since the generated XML has to appease the GUI, "%Zm" rather than "%m" was used.

 

There is no universal syntax for option names (keyword or value) as some kind of special names that would only ever evaluate to themselves. There is a long history of argument about the possible syntax for such a thing, with no consensus achieved.

And in consequence there is no universal mechanism to guard or warn against the kind of clash you describe (especially since it includes the case of future clashes, as additional user-defined procedures get created following assignment to names).

In your example you can use,

    Vector[':-row']([a,b])

That follows these two rules:
1) Use of the global name, ie. :-row
2) Protection against evaluation in case of prior assignment, through use of single forward ticks (a.k.a. uneval quotes, or single right-quotes).

If you are going to pass that quoted reference to another procedure call then you would need to protect against any additional evaluation that arguments to procedure calls normally get. Eg., if you prefer making it more complicated and doing more typing than necessary,

    convert([a,b],Vector['':-row''])

See also this Help page.

restart;
foo:=proc()
local A,row,res,a,b;
A:=Matrix([[1,1],[2,3],[4,5]]);
row:=Vector[':-row']([a,b]);
res:=ArrayTools:-Concatenate(1,A,row);
ArrayTools:-Concatenate(1,A,convert([a,b],Vector['':-row'']));
ArrayTools:-Concatenate(1,A,Vector[':-row']([a,b]));
end proc:

row:=5;
foo();

Naturally, I'll leave aside use of angle-bracket constructors for an even terser syntax, as that could defeat the illustrative purpose of your example.

It makes more sense to understand the behaviour than merely to follow advice.

restart:
v:=t->t:
plot([seq(fracdiff(v(t), t,alpha),alpha=-1..3/2,1/2)],
     t=0..10,view=[0..9.5,0..5],
     legend=[seq('alpha'=alpha,alpha=-1..3/2,1/2)],
     thickness=3,
     color = [red, blue, green,yellow,cyan,magenta],
     axis[2]=[gridlines=[linestyle=dot]]);

The inlining of .mw worksheets has been broken on Mapleprimes for a few weeks now.

It's been mentioned in at least three threads now, afaik.

I don't know whether anyone is looking into it.

It is a serious problem with the Mapleprimes site. It impacts many -- if not most -- of the people contributing here.

Yes, people have been resorting to quoted plaintext pieces of code. (I switch to raw html mode and use the <pre> tag, which can be awkward when `<` and `&` have to be properly escaped, etc.)

This site has some longstanding bugs, eg.
 1) inlined worksheets get their plots converted via conversion to JPEG, which looks terrible, instead of PNG which looks great.
 2) inline 2D plots are rendered by the Mapleprimes backend to show with gridlines, even if the plots were created without them. (One has to explcitly compute with gridlines=false, to preven this ugly effect.)
 

I don't know whether your example is a "toy example", created purely to illustrate your query about the implicitplot command. But, on the chance that you are not aware, you can usually produce a smoother plot -- more quickly and while utilizing fewer data points -- though an explicit representation if available.

Also, the regular plot command operating on an explicit expression attempts adaptive sampling of points, by default, so that fewer data points are used where the curve is smoother.

Perhaps key here, also, is an old issue with anti-aliasing of 2D plots rendered in the GUI, according to the number of data points.

And so you may compare the results of these, in your Maple GUI. I have toggled off adaptive plotting, in the last four calls, so as to force a fixed number of data points, so as to illustrate one of the (known) anti-aliasing problems that might exist in your Maple version.

[edit. The cutoff at which anti-aliasing is disabled is 2000 points in my Maple 2020.1 for Linux. IIRC, this limit can also be worked around pretty easily by splitting CURVES plotting substructures using subsindets. But keep in mind that that would often be unnecessary, as a smooth curve may often be rendered using far fewer points -- like for the given example.]

restart:
F:=(x,y) -> -(1/2)*(25*(-2/25+y^2*(x^2+1)))*(1/2)^((-x^2+1)/(x^2+1))+4*(1/2)^(2*x^2/(x^2+1))*(1/25)+5*y^2*(1/2)^(-2*x^2/(x^2+1));
S := solve(F(x,y),y,explicit):

plot(S[1], x=0..20);

plot(S[1], x=0..20, adaptive=false, numpoints=512);
plot(S[1], x=0..20, adaptive=false, numpoints=4096);

plot(S[1], x=0..20, adaptive=false, numpoints=1999);
plot(S[1], x=0..20, adaptive=false, numpoints=2000);

See also the adaptive option for 2D plot.

One of you queries seems to be about whether you can write a constructed GUI Table (such as Tabulate embeds in a worksheet) to a new and separate .mw file. Here is how you can do that, programatically.

restart;
M := LinearAlgebra:-RandomMatrix(5,2);

str := DocumentTools:-ContentToString(
         DocumentTools:-Layout:-Worksheet(
           DocumentTools:-Tabulate(M, widthmode=pixels,
                                      width=400,
                                      output=XML))):
#
# For fun, this displays it in a new GUI tab.
#
:-Worksheet:-Display( str );

#
# This writes the Table to a new .mw file.
#
# Edit the filename and location as you choose. You 
# certainly don't have to use TemporaryDirectory or
# TemporaryFilename.
#
fname := FileTools:-TemporaryFilename(
            cat(FileTools:-TemporaryDirectory(),"/"), ".mw" ):
FileTools:-Text:-WriteFile( fname, str ):

#
# For fun, you can display that file in a new GUI tab.
#
:-Worksheet:-DisplayFile( fname );

tabulate_mw.mw

That would allow you to get some nice color, headers, and even some formulas if you wanted. And I suspect that you might export the worksheet (manual right-click) to PDF format.

But you might also use printf alongside writeto (or appendto), or just fprintf, if you would be satisfied with a text file. Try Carl's suggestion to handle special characters in printf, but writing to your text file.

It's a bit tricky to answer here, without knowing precisely what are your final goals. Is it a full report, or just part of it? As text file? With the data accessible from the file, or not? Etc.

It may well assist you later on to understand that your central problem here is not due to the presence of a conditional.

In fact your code can be modified to work with if..then, as well as with piecewise.

The central problem was that the global name H in the expressions assigned to Rehf, PL1, and PL2 was not the same as the name H appearing as the parameter of your procedure. Hence neither the evaluation of Rehf in the conditional test nor the evaluation of PL1,PL2 were working as you wanted within that procedure.

It turns out that using piecewise is terser and neater than using if..then, and using an expression rather than a procedure is terser still. But the reason those work better that your original lies in how the name H is being evaluated, and not because you were wrong to use if..then.

And you could also have fixed up the evaluation within the procedure. or you could use unapply to construct a procedure with the same, matching instance of name H as parameter.

This whole evaluation issue is quite common. It was not an if...then problem. Your example just happened to involve a conditional. The original wouldn't have produced any plot even if it always returned just PL1.

These all work, because they fix the central problem of evaluation of H within Rehf, PL1, and PL2.

restart:
nuhf:=0.294*10^(-6):
Rehf:=Vhf*H/nuhf:
Vhf:=0.5:
rhohf:=965.31:
Lhs:=2.5*10^(-3):
DP1:=f1*Lhs*rhohf*Vhf^2/(2*H):
f1:=4*18.3/Rehf:
Whs:=1:
mhf:=rhohf*Vhf*Whs*H:
Rehf:=Vhf*H/nuhf:
PL1:=DP1*mhf/rhohf:
DP2:=f2*Lhs*rhohf*Vhf^2/(2*H):
f2:=0.3164/(Rehf^(0.25)):
PL2:=DP2*mhf/rhohf:

procd:=proc(H)
    if eval(Rehf,:-H=H)<1000 then
      eval(PL1,:-H=H);
    elif eval(Rehf,:-H=H)>1000 then
      eval(PL2,:-H=H);
    else
      0;
    fi;
end:
plot(procd, 0..0.002);
plot('procd(H)', H=0..0.002);

procd2:=unapply(piecewise(Rehf<1000, PL1, Rehf>1000, PL2),H):
plot(procd2, 0..0.002);
plot('procd2(H)', H=0..0.002);

exprd:=piecewise(Rehf<1000, PL1, Rehf>1000, PL2):
plot(exprd, H=0..0.002);

Here is one way, using a variant on your call to VolumeOfRevolution.

QuestionOptionVolume_ac.mw

Your methodology to check where the csgn is positive seems a consequence of your given example.

Why shouldn't there be some other example where the odetest result becomes zero when a csgn subexpression is negative, or when some mix of conditions attain due say to cancellation amongst several csgn instances?

What logical or mathematical justification do you have that you can generally find the conditions by examining only the arguments to csgn subexpressions? Why would that be valid?

[edit: I should be more clear. Your methodology, as presented, is generally invalid.]

Why not try to compute directly the solution to the actual problem of where res the odetest result becomes zero, possibly under the condition that x is real?

Perhaps you could start by trying something straightforward like, say,
    solve(simplify(res)) assuming real;
(possibly testing finite end-points of ranges, singletons, and singular points separately) and then trying to refine the approach when harder examples arise?

For example,

restart;
ode :=diff(y(x),x)=2*(x*sqrt(y(x))-1)*y(x):
ic  :=y(0)=1:
sol :=dsolve([ode,ic]):

res :=odetest(sol,ode):

lprint(res);
-2*x/(x+1)^3*csgn(1/(x+1))+2*x/(x+1)^3

solve(simplify(res)) assuming real;
                 RealRange(Open(-1), infinity)

note: The example you present is here the same as a followup example you just added to your previous Question on this same topic. In that thread I wrote about the matter of possible realness of the solution, and I made use of assuming it in my Answer's handling of several of your examples. That matter still seems germane.

First 97 98 99 100 101 102 103 Last Page 99 of 336