acer

32400 Reputation

29 Badges

19 years, 344 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

Your first use of PDEtools[declare] makes psi(t) appear as just psi in output. But it doesn't affect input, and in your usage you'd still need to type psi(t) if you want to refer to it.

The Physics:-diff command will allow you to differentiate with respect to psi(t).

The name theta__l gets prettyprinted with an underscore. You could use another name if you'd prefer to avoid that.

restart

PDEtools[declare](`θ__l`(t), `β__l`(t), `θ__si`(t), `β__si`(t), psi(t), x(t), z(t)); PDEtools[declare](prime = t)

`derivatives with respect to`*t*`of functions of one variable will now be displayed with '`

V__1lx := diff(x(t), t)-(1/2)*l__b*sin(psi(t))*(diff(psi(t), t))-l__1c*sin(`θ__l`(t)-psi(t))*(diff(`θ__l`(t), t)-(diff(psi(t), t))); V__1lz := diff(z(t), t)-(1/2)*l__b*cos(psi(t))*(diff(psi(t), t))-l__1c*cos(`θ__l`(t)-psi(t))*(diff(`θ__l`(t), t)-(diff(psi(t), t)))

V__1l := simplify(V__1lx^2+V__1lz^2, size)

(diff(x(t), t)-(1/2)*l__b*sin(psi(t))*(diff(psi(t), t))+l__1c*sin(-theta__l(t)+psi(t))*(diff(theta__l(t), t)-(diff(psi(t), t))))^2+(diff(z(t), t)-(1/2)*l__b*cos(psi(t))*(diff(psi(t), t))-l__1c*cos(-theta__l(t)+psi(t))*(diff(theta__l(t), t)-(diff(psi(t), t))))^2

Physics:-diff(V__1l, psi(t))

2*(diff(x(t), t)-(1/2)*l__b*sin(psi(t))*(diff(psi(t), t))+l__1c*sin(-theta__l(t)+psi(t))*(diff(theta__l(t), t)-(diff(psi(t), t))))*(-(1/2)*l__b*cos(psi(t))*(diff(psi(t), t))+l__1c*cos(-theta__l(t)+psi(t))*(diff(theta__l(t), t)-(diff(psi(t), t))))+2*(diff(z(t), t)-(1/2)*l__b*cos(psi(t))*(diff(psi(t), t))-l__1c*cos(-theta__l(t)+psi(t))*(diff(theta__l(t), t)-(diff(psi(t), t))))*((1/2)*l__b*sin(psi(t))*(diff(psi(t), t))+l__1c*sin(-theta__l(t)+psi(t))*(diff(theta__l(t), t)-(diff(psi(t), t))))

``

Download DiffExpr_ac.mw

You could use the DocumentTools:-Tabulate command to embed a GUI Table of values. The values and column headings are constructed in a Matrix.

In the attached, I show two ways to handle the column headings (y3 and y4, with the formula for the latter shown explicitly). You can make both column headers the same, of course, using which form you prefer.

The attached also shows a variant of the above is to use a DataFrame structure instead of a Matrix, but I find that a little awkward.

The Tabulate command has several options, which allow you to customice the cell coloring, border display, column weighting, Table width, etc.

NULL

Example: Verifying Inverse Functions Numerically

 

"ex17f6(x):=(x-5)/(2);"

proc (x) options operator, arrow, function_assign; (1/2)*x-5/2 end proc

"ex17g6(x):=2 x+5;"

proc (x) options operator, arrow, function_assign; 2*x+5 end proc

y3:=ex17f6@ex17g6;

`@`(ex17f6, ex17g6)

y4:=ex17g6@ex17f6;

`@`(ex17g6, ex17f6)

NULL

V1 := Vector(7, proc (i) options operator, arrow; i-3 end proc); M := `<|>`(V1, map(y3, V1), map(y4, V1))

T := `<,>`(`<|>`("x", "y3", InertForm:-Display(%ex17g6(%ex17f6(x)), inert = false)), M)

``

DocumentTools:-Tabulate(T, fillcolor = (proc (T, i, jj) options operator, arrow; `if`(i = 1, cyan, white) end proc))

 

x

y3

Typesetting:-_Hold([%ex17g6(%ex17f6(x))])

-2

-2

-2

-1

-1

-1

0

0

0

1

1

1

2

2

2

3

3

3

4

4

4

 

 

 

Tabulate(DataFrame(`<|>`(map(y3, V1), map(y4, V1)), columns = [InertForm:-Display(%ex17f6(%ex17g6(x)), inert = false), "y4"], rows = [`$`(-2 .. 4)]))

 

 

Typesetting:-_Hold([%ex17f6(%ex17g6(x))])

y4

-2

-2

-2

-1

-1

-1

0

0

0

1

1

1

2

2

2

3

3

3

4

4

4

 

 

InverseNum_ac.mw

You can do this with either a procedure or an expression. In other words, you really don't have to use unapply. I'll show both, below.

I'm guessing that you want to use several values between 0 and 1, in which case you can supply a 3rd argument to to seq to specify the increment.

For example,

restart;

seq(x, x = 0 .. 1, 0.25);

0, .25, .50, .75, 1.00

f := unapply(3*x^2-2*x^3-1.080674649*x^2*(x-1)^2
             -.8118769171*x^2*(x-1)^3+.4147046974*x^2*(x-1)^4
             +.4585681954*x^2*(x-1)^5, x):

seq(f(x), x = 0 .. 1, 0.25);

0., .1410641163, .4607261850, .8135524863, 1.000000

F := 3*x^2-2*x^3-1.080674649*x^2*(x-1)^2
     -.8118769171*x^2*(x-1)^3+.4147046974*x^2*(x-1)^4
     +.4585681954*x^2*(x-1)^5:

seq(F, x = 0 .. 1, 0.25);

0., .1410641163, .4607261850, .8135524863, 1.000000

L := [seq([x,F], x = 0 .. 1, 0.1)];

[[0, 0.], [.1, 0.2517819625e-1], [.2, 0.9374594496e-1], [.3, .1954298021], [.4, .3207056009], [.5, .4607261850], [.6, .6065902371], [.7, .7481833253], [.8, .8728222816], [.9, .9639340323], [1.0, 1.000]]

#plots:-display(plot(L,style=point),plot(F,x=0..1));

 

Download seq_range.mw

 

One of the basic things to learn in Maple is the distinction between expressions and procedures. (An operator is a special kind of procedure that displays with the arrow notation.)

I realize that you may be quite used to instructors and textbooks using the term "function". But using that term in the context of Maple code can be confusing, since people might not always understand whether you mean expression or procedure.

Also, while your example can indeed work using operators, there's really no need for them here. The combine simplification needs expressions, and explicitly putting combine into the procedure body is inefficient.

There's little to no merit in using an operator f if you are just going to invoke it as f(x) every time you want to do a computation with expressions. It'd be simpler and cleaner to just use an expression directly.

In 2D Input mode the syntax,
   f(x,y) := ...something...
is an alternate syntax for assigning the operator,
   f := (x,y) -> ...something...
Unfortunately the first of those does something quite different in 1D plaintext Maple notation (or with different 2D Input preferences) and so it is ambiguous in the Maple language. I suggest that you think hard about whether you want to use ambiguous Maple syntax just to get a familiar looking math look & feel. I use the second form, below.

restart


The folowing assigns expressions to names F and G.

F := sin(x)*cos(y)

sin(x)*cos(y)

G := sin(y)*cos(x)

sin(y)*cos(x)


These expressions can be subtracted, directly. The result is also
an expression.

Notice that the "simplification" you want is not automatic.

F-G

sin(x)*cos(y)-sin(y)*cos(x)

V := combine(F-G)

sin(x-y)

eval(V, [x = Pi, y = (1/3)*Pi])

(1/2)*3^(1/2)

restart


The following assigns operators (a kind of procedure) to names f and g.

f := proc (x, y) options operator, arrow; sin(x)*cos(y) end proc

proc (x, y) options operator, arrow; sin(x)*cos(y) end proc

g := proc (x, y) options operator, arrow; sin(y)*cos(x) end proc

proc (x, y) options operator, arrow; sin(y)*cos(x) end proc


If we apply  these f and g operators to arguments (eg, x,y or some
other pair of names) then the result happens to be an expression.

f(x, y)

sin(x)*cos(y)

f(s, t)

sin(s)*cos(t)

f-g

f-g


The difference, f-g, can also be used like a operator. The result here is
also an expression.

(f-g)(x, y)

sin(x)*cos(y)-sin(y)*cos(x)


You have to apply the operators, to obtain expressions, in order
to use the combine command to obtain the simplification you want.

combine((f-g)(x, y))

sin(x-y)

``

f(x, y)-g(x, y)

sin(x)*cos(y)-sin(y)*cos(x)

combine(f(x, y)-g(x, y))

sin(x-y)


If you really want the combined expression to be the body of a new
operator then you can use the unapply  command.

v := unapply(combine((f-g)(x, y)), [x, y])

proc (x, y) options operator, arrow; sin(x-y) end proc

v(Pi, (1/3)*Pi)

(1/2)*3^(1/2)


Another solution is to construct a new operator that calls the
combine command each time it is invoked. This is somewhat
inferior because its use could be inefficient -- calling
combine on every result (f-g)(x,y) (which might not always
be just a number) each and every time v2 got called.

v2 := proc (x, y) options operator, arrow; combine((f-g)(x, y)) end proc

proc (x, y) options operator, arrow; combine((f-g)(x, y)) end proc

v2(x, y)

sin(x-y)

``

Download expr_oper_combine.mw

 

Your code has several mistakes.

Why do you have Ps[i][] in the odeplot call, when Ps is not a list of lists? The use of Ps and Pc is all muddled up. Explain, properly, what your intention is for those.

Why do you have theta(eta) in the odeplot call? Did you intend f(eta) or something else?

Where did you copy the code from? Was it from an earlier Question on Mapleprimes -- perhaps from someone taking the same course, before you?

I have a suggestion: instead of simply trying to reuse (someone else's?) object-oriented, (and undocumented?) code you should either learn how each part of it works, or try to program the task yourself in simple steps. That way you might actually learn how to use Maple for solving such bvp problems, and it'd help you in your future tasks as well.

This is a common issue, especially for coders new to Maple.

You made the central and germane statement, "It appears that fieldplot3d is attempting to evaluate the statements within the procedure, instead of simply calling the procedure with numerical values." It is excellent that you got to that idea. You are correct. Maple's usual model of evaluation during procedure calls is to evaluate the arguments up front, before the procedure body does the computation.

Sometimes (like in your problematic example) this situation is referred to as premature evaluation. The procedure PUV was not prepared to deal with some nonnumeric arguments. And, for symbolic arguments (x,y,z), the function call PUV(x,y,z) was evaluated prematurely.

The most common scenario for encountering this problem is with an if..then statement. In fact, if you click on the magenta error message in your Document then (provided your Maple GUI is set up to call your web browser) it will take you to this Help page which addresses this issue. In your original worksheet, if you call PUV(x,y,z) by itself then you'll see the same error message.

For your example the cleanest way to resolve this problem is to alter the body of your procedure so that it can handle nonnumeric arguments. Member Kitonum's Answer shows that you can simply utilize 2-argument arctan and remove the conditional queries. And member Preben Alsholm's Answer explains that you can utilize a piecewise structure and so defer the conditional branching until a numeric value is supplied.

But those kind of approaches are not always easy to accomplish gracefully. So, for fun in these lockdown times, we can take a brief look at some blunter methods.

The Help page to which I linked shows two ways to deal with the issue. There is an extra wrinkle, however, in the fact that fieldplot3d needs three items (expressions in a list, or expressions in a Vector, or procedures in a list). But otherwise the approaches illustrated in that Help page are still possible:
1) Delay the up-front evaluation of the function call using right (forward) single-quotes, aka uneval-quotes. Here is that approach, for your example. fieldplot3d_and_if_statements_ac1.mw
2) Use the operator form calling-sequence of fieldplot3d, instead of the expression form. That is shown in member vv's Answer.

I'll also give a variant on 1), since uneval-quotes are ephemeral:
3) You could adjust the procedure PUV so that it returns unevaluated if some of the arguments are not numeric. fieldplot3d_and_if_statements_ac2.mw

Approaches 1) and 3) both index into the unevaluated function call since in those cases three expressions need to be passed for fieldplot3d and, when numeric x-y values get substituted, each result from PUV will be a Vector. Approach 2) also involves indexed calls to PUV, for the same reason. So all of these approaches actually call PUV three times for every numeric x-y pair. In order not to make triple the computational effort the procedure PUV can be given option remember, so that the second and third call (with the same, repeated numeric x-y pair) can be done with a quick lookup of a stored result.

You can increase Digits and call the LPSolve command from the Optimization package.

See the Help pages with those terms as Topic.

You might be making the mistake of using lowercase pi instead of Pi.

If I accidentally use the "Evaluate at a Point" context-menu item and supply lowercase 2*pi as the value for t then I'll get the same result as you. But lowercase pi is just a name, with no special meaning to Maple.

But if I use the capitalized Pi in the "Evaluate at a Point" context-menu item, and supply 2*Pi as the value for t then the output is the expected result.

g := t*(cos(t)+I*sin(t))

t*(cos(t)+I*sin(t))

expr := diff(g, t)

cos(t)+I*sin(t)+t*(-sin(t)+I*cos(t))

"(->)"

1+(2*I)*Pi

eval(expr, t = 2*Pi)

1+(2*I)*Pi

eval(expr, t = 2*pi)

cos(2*pi)+I*sin(2*pi)+2*pi*(-sin(2*pi)+I*cos(2*pi))

evalf(Pi)

3.141592654

evalf(pi)

pi

``

Download Pi_versus_pi.mw

S := -A/Pi*Sum((-1)^k*sin(2*Pi*k*f*(t-Pi/8))/k,k=1..N):

bg := plots:-display(
  plot(fmod(t,Pi/4)*4/Pi-1/2,t=0..Pi,color=blue,thickness=1),
  plots:-pointplot([seq([[i*Pi/4,0.5],[(i-1)*Pi/4,-0.5]][],i=1..4)],
                   symbol=solidcircle,symbolsize=8,color=white),
  plots:-pointplot([seq([[i*Pi/4,0.5],[(i-1)*Pi/4,-0.5]][],i=1..4)],
                   symbol=circle,symbolsize=12,color=blue)):

F := n -> plots:-display(bg,
    plot(eval(S,[A=1,f=4/Pi,:-N=round(n)]),t=0..Pi,
         thickness=1,color=red,numpoints=max(2,10*round(n))),
    plots:-textplot([0.35,-1.0,sprintf("N = %-2ld",round(n))],
                    font=["Monospaced","bold"])):

L := [0$8, 1$8, 2$8, 3$8, $4..49, 50$12]: # delay by repeating
plots:-animate(F,[N],N=L,frames=nops(L),paraminfo=false,
               xtickmarks=[],ytickmarks=[],axis[2]=[color=white],
               axis[1]=[color="#9090FF",thickness=0],size=[600,300],
               labels=[``,``],view=[Pi/16..Pi-Pi/16,-1.25..1.25]);

That is a set

See the set Help page, and in particular its Description section which should make clear the distinction between a list and a set.

When you're looking at a Help page it's often useful to give a quick glance at the "See Also" links. In this case you could also look at the Help pages for topic type/set and selection .

a := {"bar", "foo"}:

whattype(a);
               set

op(0, a);
               set

type(a, set);
               true

type(a, list);
               false

The entries of a set are stored as an expression sequence, which is also true for a list. The main differences are that the set entries are uniquified (duplicates removed) and reordered automatically, while list enties can have duplicates and are stored in a specified order.

op(a);
            "bar", "foo"

{"bar", "foo"};
           {"bar", "foo"}

{"foo", "bar", "foo"};
           {"bar", "foo"}

["bar", "foo"];
           ["bar", "foo"]

["foo", "bar", "foo"];
         ["foo", "bar", "foo"]

If you are looking to plot the integral against a variable upper limit of integration then these compute very quickly.

restart

expr := 2*sqrt((a^2+1)/(x^2+1))/sqrt((x^2+1)*exp(4*m*(arctan(a)-arctan(x)))-a^2-1)

pars := [m = 1, a = 3]

F := subs(integrand = unapply(eval(expr, pars), x), proc (X) options operator, arrow; evalf(Int(integrand, eval(a, pars) .. X, method = `if`(X = infinity, _d01amc, _d01ajc), epsilon = 0.1e-6)) end proc)

proc (X) options operator, arrow; evalf(Int(proc (x) options operator, arrow; 2*10^(1/2)*(1/(x^2+1))^(1/2)/((x^2+1)*exp(4*arctan(3)-4*arctan(x))-10)^(1/2) end proc, eval(a, pars) .. X, method = `if`(X = infinity, _d01amc, _d01ajc), epsilon = 0.1e-6)) end proc

F(4), F(infinity)

2.488627376, 5.507527357

plot([F, F(infinity)], 3 .. 200)

plot([F, F(infinity)], 3 .. 10^3, axis[1] = [mode = log])

plot([F, F(infinity)], 3 .. infinity)

 

Download integral_test_ac.mw

Here are two approaches, the first of which does not need Digits raised high, and is pretty quick and not very complicated. Neither is terribly slow. Do the results concur with your expectation?

Were you hoping to see some explicit rearrangement of terms, so that avoiding numeric difficulties (roundoff and loss of precision, say) were more transparent?

I used Maple 16.02.

restart

Digits := 20

20

y1 := C1[1, 1]*sin(alpha*x)+C1[1, 2]*cos(alpha*x)+C1[1, 3]*sinh(beta*x)+C1[1, 4]*cosh(beta*x)

C1[1, 1]*sin(alpha*x)+C1[1, 2]*cos(alpha*x)+C1[1, 3]*sinh(beta*x)+C1[1, 4]*cosh(beta*x)

y2 := C1[2, 1]*sin(alpha*x)+C1[2, 2]*cos(alpha*x)+C1[2, 3]*sinh(beta*x)+C1[2, 4]*cosh(beta*x)

C1[2, 1]*sin(alpha*x)+C1[2, 2]*cos(alpha*x)+C1[2, 3]*sinh(beta*x)+C1[2, 4]*cosh(beta*x)

fun1 := Int(y1^4, x = 0 .. 5*(1/100))+Int(y2^4, x = 5*(1/100) .. 1);

Int((C1[1, 1]*sin(alpha*x)+C1[1, 2]*cos(alpha*x)+C1[1, 3]*sinh(beta*x)+C1[1, 4]*cosh(beta*x))^4, x = 0 .. 1/20)+Int((C1[2, 1]*sin(alpha*x)+C1[2, 2]*cos(alpha*x)+C1[2, 3]*sinh(beta*x)+C1[2, 4]*cosh(beta*x))^4, x = 1/20 .. 1)

vals := [alpha = 3.093676148361444, beta = 1.136458914000455*10^2, C1[1, 1] = 1.000000000000000, C1[1, 2] = 0, C1[1, 3] = -0.22069165109e-4, C1[1, 4] = 0, C1[2, 1] = .764799945371359, C1[2, 2] = 0.36674613077895e-1, C1[2, 3] = .95132568684786, C1[2, 4] = -.95132568684786]:

evalf(expand(convert(eval(fun1, vals), exp)));

.13088320034942916574

with(IntegrationTools):

Digits := 100;

100

F2fun1 := Change(Change(op(2, fun1), x = (1*1)*(19*u+1/20), u), u = x, x):

Int((C1[1, 1]*sin(alpha*x)+C1[1, 2]*cos(alpha*x)+C1[1, 3]*sinh(beta*x)+C1[1, 4]*cosh(beta*x))^4+19*(C1[2, 1]*sin((1/20)*alpha*(380*x+1))+C1[2, 2]*cos((1/20)*alpha*(380*x+1))+C1[2, 3]*sinh((1/20)*beta*(380*x+1))+C1[2, 4]*cosh((1/20)*beta*(380*x+1)))^4, x = 0 .. 1/20)

0

new := eval(F2, vals):

map(proc (k) options operator, arrow; k end proc, convert(new, exp)):

.1308832003494291657430777664602299881224552490777598299889111954482828996588502290591220342036629305

``

Download question_ac.mw

You can save some work by having your rm procedure return both the remainder as well as the quotient.

A surrounding procedure can store the quotients in a table (I used the name T), and then -- when finished -- it can construct a list from the entries stored in T.

It would be inefficient to repeatedly augment a list in a loop. So don't do something like the statement in a loop, for list L,
  L := [op(L), func(a, b)];
That's why I stored the quotients in a table, and only at the end turned that into a list.

(Your could also use irem instead of your rm procedure, but I suppose this is a programming exercise. Also see convert(..., base, ...) .)

restart;

rm := proc(a, b) local n; n := 0;
  while 0 <= b - n*a do b - n*a; n := n + 1; end do;
  return n - 1 , b - (n - 1)*a;
end proc:

cv := proc(a::posint, b::posint)
 local T,i,j,r;
 r := b;
 for i while r <> 0 do
   r,T[i] := rm(a,r);
   #T[i] := irem(r,a,'r')
 end do;
 if i = 1 then
   [0]
 else
   [seq(T[j],j = 1 .. i-1)]
 end if;
end proc:

cv(8, 3657);
                          [1, 1, 1, 7]

convert(3657,base,8);
                          [1, 1, 1, 7]

The  LinearAlgebra,General,LinearSolveItr  help page is missing details for the nonsymmetric solver.

But the method can be supplied using the methodoptions optional parameter, similar to how it is documented for the symmetric solver.

(One could examine the code, to figure out additional suboptions that control the methods.)

restart;

with(LinearAlgebra):

infolevel[LinearAlgebra]:=3:

M := Matrix(4,4,[[5.0,0.0,1.0,0.0],[0.2,-1.0],[0.0,3.0,0.0],[-2.0,0.0,0.0,1.0]],
            storage=sparse, datatype=float):

b := Vector(4,1.0,datatype=float):

X := LinearSolve(M,b,method=SparseIterative,methodoptions=[itermethod=CGS]);

LinearSolve: using method SparseIterative

LinearSolve: using method SparseIterative
LinearSolve: calling external function
LinearSolve: using CGS method
LinearSolve: preconditioning with incomplete LU factorization
LinearSolve: level of fill =  0
LinearSolve: using complete pivoting strategy
LinearSolve: dimension of workspaces for preconditioner =  30
LinearSolve: using infinity norm in stopping criteria
LinearSolve: setting maximum iterations to  200
LinearSolve: setting tolerance to  0.10e-7
LinearSolve: NAG hw_f11zaf
LinearSolve: NAG hw_f11daf
LinearSolve: NAG hw_f11dcf
LinearSolve: number of iterations 1
LinearSolve: residual computed last as HFloat(1.1102230246251565e-16)

_rtable[18446884364565750718]

M.X - b;

unknown: hw_SpMatVecMulRR

_rtable[18446884364565751918]

LinearSolve(M,b,method=SparseIterative,methodoptions=[itermethod=RGMRES]);

LinearSolve: using method SparseIterative

LinearSolve: using method SparseIterative
LinearSolve: calling external function
LinearSolve: using RGMRES method
LinearSolve: preconditioning with incomplete LU factorization
LinearSolve: level of fill =  0
LinearSolve: using complete pivoting strategy
LinearSolve: dimension of workspaces for preconditioner =  30
LinearSolve: using infinity norm in stopping criteria
LinearSolve: setting maximum iterations to  200
LinearSolve: setting tolerance to  0.10e-7
LinearSolve: NAG hw_f11zaf
LinearSolve: NAG hw_f11daf
LinearSolve: NAG hw_f11dcf
LinearSolve: number of iterations 2
LinearSolve: residual computed last as HFloat(1.7763568394002505e-15)

_rtable[18446884364565752758]

LinearSolve(M,b,method=SparseIterative,methodoptions=[itermethod=BICGSTAB]);

LinearSolve: using method SparseIterative

LinearSolve: using method SparseIterative
LinearSolve: calling external function
LinearSolve: using Bi-CGSTAB method
LinearSolve: preconditioning with incomplete LU factorization
LinearSolve: level of fill =  0
LinearSolve: using complete pivoting strategy
LinearSolve: dimension of workspaces for preconditioner =  30
LinearSolve: using infinity norm in stopping criteria
LinearSolve: setting maximum iterations to  200
LinearSolve: setting tolerance to  0.10e-7
LinearSolve: NAG hw_f11zaf
LinearSolve: NAG hw_f11daf
LinearSolve: NAG hw_f11dcf
LinearSolve: number of iterations 1
LinearSolve: residual computed last as HFloat(4.440892098500626e-16)

_rtable[18446884364365961446]

 

Download sparseiterative.mw

If I recall, there's no nice, efficient functionality to apply the preliminary work (preconditioning, etc) to multiple RHSs in separate calls. (I could be misremembering -- I didn't check.)

In Maple 2020 you could use printf with the new P format. Or you could use print.

Of course, you could also use sprintf if you prefer a string as return value.

The rules for when if...then...end clauses get indented are not clear to me.

The example below using print does render with more indentation in the Maple GUI than appears when inlined below. And that survives cut&paste, in my Linux.

[edit] One thing that I prefer about the printf format is that it displays semicolon terminators even when optional (eg. before an end). Of course that is a personal preference. I like that it helps prevent a sloppy typo if an extra line is inserted inbetween (or via an $include).

Another thing -- that might matter in some use cases -- is that printf doesn't contain the extra decoration at the start (ie. the printed name and colon-equals) and it's easier to add it than remove it.

restart;

kernelopts(version);

`Maple 2020.0, X86 64 LINUX, Mar 4 2020, Build ID 1455132`

f := proc(x)
   if x <= 2 then
     if x>0 then
       print(-x);
     else
       print(-x^2);
     end if;
   else
     if x>0 then
       print(-x);
     end if;
   end if;
   print(-x);
   x^3;
   if x <= 2 then
     if x>0 then
       if x > -5 then
         print(-x);
       end if;
     else
       print(-x^2);
     end if;
   else
     if x>0 then
       if x > -5 then
         print(-x);
       end if;
     end if;
   end if;
end proc:

 

printf("%P", eval(f));

proc(x)
    if x <= 2 then
        if 0 < x then print(-x); else print(-x^2); end if;
    else
        if 0 < x then print(-x); end if;
    end if;
    print(-x);
    x^3;
    if x <= 2 then
        if 0 < x then
            if -5 < x then print(-x); end if;
        else
            print(-x^2);
        end if;
    else
        if 0 < x then if -5 < x then print(-x); end if; end if;
    end if;
end proc

 

showstat(f);


f := proc(x)
   1   if x <= 2 then
   2       if 0 < x then
   3           print(-x)
           else
   4           print(-x^2)
           end if
       else
   5       if 0 < x then
   6           print(-x)
           end if
       end if;
   7   print(-x);
   8   x^3;
   9   if x <= 2 then
  10       if 0 < x then
  11           if -5 < x then
  12               print(-x)
               end if
           else
  13           print(-x^2)
           end if
       else
  14       if 0 < x then
  15           if -5 < x then
  16               print(-x)
               end if
           end if
       end if
end proc
 

print(f);

proc (x) if x <= 2 then if 0 < x then print(-x) else print(-x^2) end if else if 0 < x then print(-x) end if end if; print(-x); x^3; if x <= 2 then if 0 < x then if -5 < x then print(-x) end if else print(-x^2) end if else if 0 < x then if -5 < x then print(-x) end if end if end if end proc

 

 

Download format_P.mw

First 125 126 127 128 129 130 131 Last Page 127 of 336