acer

13691 Reputation

29 Badges

12 years, 55 days

On google groups. (comp.soft-sys.math.maple and sci.math.symbolic)

On stackoverflow.

On math.stackexchange.com.

MaplePrimes Activity


These are answers submitted by acer

See the Grid package.

You could also look at the Threads package (but I suspect that it will not be suitable, if your computations involve code the is not thread-safe).

There is an undocumented export Hyperlink of the DocumentTools:-Layout subpackage.

You cannot get a hyperlink in regular printed output, but you can include it in embedded content.

hyperlink_embed.mw

With an explicit expression (formula) for the individual terms you can do symbolic summation using the sum command. For your example the summation can be computed to a closed-form expression formula, whose exact limit can then be taken, as Kitonum has shown.

But with a procedure that only computes the addition of a particular number of terms the limit command will not see any formula and so exact computation of the limit cannot be done. The procedure is then a black-box, as far as the limit command is concerned.

With such a procedure it is still possible to compute the limit to a non-exact floating-point value, by using a command that numerically computes the addition of various finite numbers of terms and then determines whether those results converge.

restart;

 

p:=proc(n)
  local i,su;
  su:=0;
  for i from 1 to n do
    su := su+(2*i/n)*(2/n);
  end do;
  return su;
end proc:

p(1), p(2), p(3), p(4);

4, 3, 8/3, 5/2

limit(p(n), n=infinity);

Error, (in p) final value in for loop must be numeric or character

 

That error occurs because the p(n) is evaluated prematurely. That is to say, before
the limit command gets to work Maple first evaluated the first argument. We can
see in the next statement that itself is producing the error.

 

p(n);

Error, (in p) final value in for loop must be numeric or character

 

We can guard against such premature evaluation by delaying evaluation (of that
first argument passed to limit) through use of single right-quotes (unevaluation quotes).

 

'p'(n); # returns unevaluated

p(n)

limit('p'(n), n=infinity);

limit(p(n), n = infinity)

evalf(limit('p'(n), n=infinity));

2.000000000

Limit('p'(n), n=infinity);

Limit(p(n), n = infinity)

evalf(Limit('p'(n), n=infinity));

2.000000000

 

Another way to prevent that premature evaluation is to construct the procedure so
that it returns unevaluated if its own argument is not of the appropriate type.

 

p:=proc(n)
  local i,su;
  if not type(n,posint) then
     return 'procname'(args);
  end if;
  su:=0;
  for i from 1 to n do
    su := su+(2*i/n)*(2/n);
  end do;
  return su;
end proc:

p(1), p(2), p(3), p(4);

4, 3, 8/3, 5/2

p(n); # returns unevaluated

p(n)

limit(p(n), n=infinity);

limit(p(n), n = infinity)

evalf(limit(p(n), n=infinity));

2.000000000

 


Download evalf_limit.mw

Short and simple is,

[seq(x>=0,x=A)];

In Maple 2017 one can also do it as follows (omitting use of a dummy name like x, but temporarily producing an additional sequence or list),

[seq(A)>=~0];
[seq(A)]>=~0;

 

You also asked why a particular attempt (to make similar results, but with lists of lists) failed, using the $ command.

The reason it failed is that when you call $ then Maple will evaluate the lhs argument using its usual evaluation rules for procedure calls. That means that arguments are evaluated up front, before the computations of the procedure begin. But you passed A[i,j] to the inner call to $, and that produces an error when i and j have not yet attained integer values. This kind of problem is jokingly referred to as premature evaluation. For this example you can repair that attempt by using two pairs on (unevaluation) single right-quotes to delay the evaluation of A[i,j] until i and j are numbers, because there are two nested function calls. It looks awkward. Or you can use seq instead of $.

A:=Matrix([[2,a],[b,3]]):

A[i,j];
Error, bad index into Matrix

[[(A[i,j]>=0)$i=1..2]$j=1..2];
Error, bad index into Matrix

[[(''A''[i,j]>=0)$i=1..2]$j=1..2];

              [[0 <= 2, 0 <= b], [0 <= a, 0 <= 3]]

[[seq('A'[i,j]>=0,i=1..2)]$j=1..2];

              [[0 <= 2, 0 <= b], [0 <= a, 0 <= 3]]

[seq([seq(A[i,j]>=0,i=1..2)],j=1..2)];

              [[0 <= 2, 0 <= b], [0 <= a, 0 <= 3]]

The reason that it works with seq is that the seq command has special evaluation rules.

If nops(g)>=n then g would have at least n operands, and then op(n,g) would exist.

But I suspect you are jumping the gun. Did you also intend to first check whether g were an expression of type `*` or type `+` , which means that g would be say a product or sum of terms.

Note that Maple uses several different sorts of structure and data structure. And several of those have operands, but with a different meaning for that concept. So asking about a specific operand of g only makes sense if you know what kind of animal g might be., and handle any different expected case appropriately.

Using _Maxim_'s good suggestion to instead compute the eigenvalues (which is faster than even using fsolve in an efficient way), and using the original Matrix which has since been added by the OP in a Comment, one can obtain the following:
 

In the actual worksheet the legend entries are not split with a newline. (That just happened when I uploaded here.) And if it happens in the sheet then one can un-hide the Table border and enlarge to fix.

restart;

M := `<|>`(`<,>`(2, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0), `<,>`(-1, 4, -1, 0, -1, 0, 0, 0, 0, 0, -exp(-I*x)), `<,>`(0, -1, 2, 0, 0, -1, 0, 0, 0, 0, 0), `<,>`(-1, 0, 0, 4, -1, 0, -exp(I*y), -1, 0, 0, 0), `<,>`(0, -1, 0, -1, 4, -1, 0, 0, -1, 0, 0), `<,>`(0, 0, -1, 0, -1, 4, -1, 0, 0, -1, 0), `<,>`(0, 0, 0, -exp(-I*y), 0, -1, 2, 0, 0, 0, 0), `<,>`(0, 0, 0, -1, 0, 0, 0, 2, -1, 0, 0), `<,>`(0, 0, 0, 0, -1, 0, 0, -1, 4, -1, -1), `<,>`(0, 0, 0, 0, 0, -1, 0, 0, -1, 2, 0), `<,>`(0, -exp(I*x), 0, 0, 0, 0, 0, 0, -1, 0, 2)):

str:=time[real]():

Mf := unapply(M, [x, y]):

f := proc(x, y) option remember;

  (sort@Re@LinearAlgebra:-Eigenvalues@Mf)(x, y)

end proc:

rng:=proc(i)
      local oldwarnlevel, res;
      uses Optimization;
      oldwarnlevel:=interface('warnlevel'=0);
      Digits:=Digits+5:
      res:=NLPSolve((x, y) -> f(x, y)[i], 'method'='nonlinearsimplex')[1]
           .. NLPSolve((x, y) -> f(x, y)[i], 'maximize', 'method'='nonlinearsimplex')[1];
      interface('warnlevel'=oldwarnlevel);
      Digits:=Digits-5:
      fnormal(evalf(res));
     end proc:

ranges:=[seq(rng(i), i=1..11)];

 

collist:=[seq(ColorTools:-Color("HSV",[(i-1)/11,1,1]),i=1..11)]:

P:=[seq(plot3d((i->(x,y)->f(x, y)[i])(i),
               0..2*Pi,0..2*Pi,color=collist[i]),
        i=1..11)]:

time[real]()-str;

[-0. .. .3961245229, .7639320227 .. 1.267949192, .7639320236 .. 1.267949192, 1.267949192 .. 1.999999991, 2.000000000 .. 2.000000000, 2.000000000 .. 2.000000000, 3.109916265 .. 3.267949192, 4.000000000 .. 4.732050808, 4.732050808 .. 5.236067977, 4.732050808 .. 5.236067977, 6.493959210 .. 6.732050808]

2.664

plots:-display(P);

use Typesetting in
hexcolors:=map(c->ColorTools:-RGB24ToHex(ColorTools:-ToRGB24(c)),collist):
lg := mrow(seq([mn(`if`(i=1,"      ","\n      "),
                mathbackground=hexcolors[12-i]), mn("  "),
                eval('Typesetting:-Typeset'(lambda[12-i])),mn("="),
                mn(sprintf("%.3f",op(1,ranges[12-i]))),mn(".."),
                mn(sprintf("%.3f",op(2,ranges[12-i])))][],
               i=1..11)):
end use:
Plegend:=plot([[0,0]], color=white, legend=lg, legendstyle=[location=left], axes=none):

I inserted the Table below, and its two Plot Components, using the palettes. And then I adjusted its properties, removing border, resizing, etc. In modern Maple I would have used the DocumentTools:-Tabulate command instead, but this work is dome in Maple 18.

DocumentTools:-SetProperty("Plot0",value,
                           plots:-display(P, orientation=[31,74,0], style=surface,
                                          glossiness=1.0, lightmodel=Light1));
DocumentTools:-SetProperty("Plot1",value,Plegend);

 

 

 

 

You could also pick a format you prefer.

S:=[solve(Or(op(map(u->And(lambda>=op(1,u),lambda<=op(2,u)), ranges))),lambda)];

[RealRange(0., .3961245229), 2., RealRange(4., 5.236067977), RealRange(.7639320227, 1.999999991), RealRange(3.109916265, 3.267949192), RealRange(6.493959210, 6.732050808)]

map(u->`if`(u::realcons,lambda=u,u),subsindets(S,RealRange,u->convert(lambda::u,relation)));

[And(0. <= lambda, lambda <= .3961245229), lambda = 2., And(4. <= lambda, lambda <= 5.236067977), And(.7639320227 <= lambda, lambda <= 1.999999991), And(3.109916265 <= lambda, lambda <= 3.267949192), And(6.493959210 <= lambda, lambda <= 6.732050808)]

map(u->`if`(u::realcons,lambda=u,u),subsindets(S,RealRange,u->lambda=op(1,u)..op(2,u)));

[lambda = 0. .. .3961245229, lambda = 2., lambda = 4. .. 5.236067977, lambda = .7639320227 .. 1.999999991, lambda = 3.109916265 .. 3.267949192, lambda = 6.493959210 .. 6.732050808]

[solve(Or(op(map(u->And(lambda>=op(1,u),lambda<=op(2,u)), ranges))),{lambda})];

[{0. <= lambda, lambda <= .3961245229}, {lambda = 2.}, {4. <= lambda, lambda <= 5.236067977}, {.7639320227 <= lambda, lambda <= 1.999999991}, {3.109916265 <= lambda, lambda <= 3.267949192}, {6.493959210 <= lambda, lambda <= 6.732050808}]

 


Download eigenspect.mw

To assign to theta you need colon-equals, ie.,

  theta := 

not,

  theta =

The latter just produces an equality expression (and does not assign to theta), rather than making an assignment.

You didn't correctly copy that example code.

I'll leave aside lambda=2.

I've deleted most of my original answer since I had somehow gotten one of the coefficients wrong in the RootOf, thus producing spurious nonzero imaginary parts for the solved values, which muddled me. The quick code is otherwise the same.

The following is reasonably fast, utilizing the fact that fsolve computes all 9 roots at once.

lambda4.mw

The following is in Maple 16.01, but the effects may be similar back in Maple 13.

Here are some choices in setup, for pretty-printing of derivatives.

restart;

kernelopts(version);

`Maple 16.01, X86 64 LINUX, May 6 2012, Build ID 744592`

interface(typesetting=standard):

diff(y(t),t,t)-4*diff(y(t),t)+5*y(t);

diff(diff(y(t), t), t)-4*(diff(y(t), t))+5*y(t)

interface(typesetting=extended):
Typesetting:-Settings(useprime=false, usedot=false):

diff(y(t),t,t)-4*diff(y(t),t)+5*y(t);

diff(diff(y(t), t), t)-4*(diff(y(t), t))+5*y(t)

Typesetting[DisableTypesetRule]("diff"):

diff(y(t),t,t)-4*diff(y(t),t)+5*y(t);

diff(diff(y(t), t), t)-4*(diff(y(t), t))+5*y(t)

Typesetting[EnableTypesetRule]("diff"):

Typesetting:-Settings(useprime=true, usedot=false, prime=t):

diff(y(t),t,t)-4*diff(y(t),t)+5*y(t);

diff(diff(y(t), t), t)-4*(diff(y(t), t))+5*y(t)

Typesetting:-Settings(useprime=false, usedot=true, dot=t):

diff(y(t),t,t)-4*diff(y(t),t)+5*y(t);

diff(diff(y(t), t), t)-4*(diff(y(t), t))+5*y(t)

 


Download diff_typesetting.mw

The different behavior in the following two examples makes me wonder whether/how the runtime scoping/evaluation is importantly different here, according to whether the inner procedure is "declared and assigned locally".

restart;

proc()
  local a := 0, b := 1;
  local f:=proc(x::uneval) print(x); x := b end proc;
  f(a);
end proc();
                               a
                               1

proc()
  local a := 0, b := 1;
  proc(x::uneval) print(x); x := b end proc(a);
end proc();
                               0
Error, (in unknown) illegal use of a formal parameter

Interestingly, the following "works" in Maple 10.03 but produces the error in Maple 11.00.

proc()
  local a,b;
   a := 0; b := 1;
   proc(x::uneval) print(x); x := b end proc(a);
end proc();

I also see the following item in the help page with topic updates,Maple11,compatibility

   Using the uneval or evaln parameter modifiers in procedures with
   optional or keyword parameters sometimes produced unpredicatable
   results in obscure cases. As such, the use of these modifiers has
   been improved in Maple 11, with clearly defined behavior. Some
   user-written procedures that use the troublesome combinations may
   need to have their parameter declarations slightly reorganized.

Your example does not use optional or keyword parameters, but I wonder whether these changes might have somehow affected parameter/lexical evaluation/scoping rules otherwise. (It might even be a "fix".)

[edited] I sent an email to a Maplesoft kernel developer and he confirmed that the emitted error was not expected. I will submit a bug report with details.

I'll add another variant. Experimentation shows that the behaviour can occur even when:
 - The argument passed to the inner procedure is not a local.
 - The local variable (of the outer procedure) is not assigned a value at the outer level.
 - The local variable (of the outer procedure) is referenced in the inner procedure, but not involved in the statement involving the problematic parameter.

restart;

c:=0:
proc()
  global c;
  local b;
  proc(x::uneval)
    print(x);
    #b;
    x:=1;
  end proc(c);
end proc();
                               c
                               1

restart;

c:=0:
proc()
  global c;
  local b;
  proc(x::uneval)
    print(x);
    b;
    x:=1;
  end proc(c);
end proc();
                               0
Error, (in unknown) illegal use of a formal parameter

So, it is the parameter modifier uneval (on a required parameter) being short-circuited during execution of a call to a nested anonymous procedure that happens also to reference a local from the outer level.

I figure that you don't want to have to pick off op(3,..) of a or numer(a), since that relies on visual inspection, and so would be done rather "by hand". I'd say the same thing about using applyop, which requires you to figure out visually which operand matters.

Having said that, here is something more programmatic. 

restart;

a := rho^(epsilon-1)*a__01^(-k)*(N__E2/Omega+N__E1*mu)*(K+1)/(mu);

rho^(epsilon-1)*a__01^(-k)*(N__E2/Omega+N__E1*mu)*(K+1)/mu

b:=rho^(epsilon-1)*a__01^(-k)*(N__E2/(Omega*mu)+N__E1)*(K+1);

rho^(epsilon-1)*a__01^(-k)*(N__E2/(Omega*mu)+N__E1)*(K+1)

type(denom(a), '`*`'(name)); # We're going to rely on this.

type(numer(a),`*`); # We're going to rely on this.

true

true

# Split multiplicands of numer(a) according to whether they are
# polynomial in any of the names in the product denom(a).

if type(denom(a), '`*`'(name)) and type(numer(a),`*`) then
  p1,p2 := selectremove(u->ormap(uu->degree(u,uu)>0,{op(denom(a))}),[op(numer(a))]);
  if nops(p1)>0 then
    res := expand(p1[1]/denom(a)) * `*`(op([2..],p1)) * `*`(op(p2));
  end if;
end if:
res;

rho^(epsilon-1)*a__01^(-k)*(N__E2/(Omega*mu)+N__E1)*(K+1)

 


Download div.mw

There are two kind of thing which pretty-print with subscripts. One is an indexed name, and the other is called a literal subscript.

It sounds as if you have inadvertantly used the wrong one, at some point. Or perhaps you have not been consistent in which one you used. (It's hard to tell which is the problem, without your complete worksheet.)

An indexed name is something like l[1] , l[3] . In both 1D plaintext and 2D Input mode you can just type those in as you see them here. But in 2D Input mode you can also enter those using the keystrokes such l Ctl-Shift-underscore 3, in which case the input is automatically turned into the pretty-printed, subscripted display. (In OSX on the Mac the keystrokes are Cmd-Shift-underscore I believe.) The underlying expression is still the indexed name.

A literal subscripted name has the underlying structure l__3 with two underscores. In both 1D plaintext and 2D Input mode you can just type those in as you see them here, and in 2D Input mode that automatically gets turned into the pretty-printed, subscripted display.

Download subscripts.mw

Those are name quotes.

You can convert to name, or use nprintf.

convert(x, name);
nprintf("%a", x);

If you are wanting this in order to concatenate multiple items as names, then note that nprintf can often do all those steps in one command.

[edited] note that this operation affects the printing. For example `1/2` will not pretty-print the same way that 1/2 does. In your related recent Questions that aspect turned out to be important to you.

I deliberately avoided mentioning symbol above. I figured that indexed names would just add confusion here.

I suspect that the OP only asked this Question so that he could use || to concatenate many items to a name. I also suspect that that's not the right approach anyway, since pretty-printing of the math terms might in fact be wanted.

The nprintf command is more suitable and straightforward than cat, for such concatenation (to a name).

restart;

Sol1:=1/4: Sol2:=1/5: Sol3:=1/7:

nprintf("Solution : A=%a, B=%a, C=%a.",Sol1,Sol2,Sol3);

`Solution : A=1/4, B=1/5, C=1/7.`

 


Download nprintf.mw

If you don't need the 1/2 pretty-printed as 2D Math then I suggest you go with Rouben's straightforward suggestion.

But if you want the 1/2 as an exact value and typeset in 2D Math then you could do it as follows. (There first example displays in the Maple's Standard GUI with the desired space after the word "for". That space is missing below due to a bug in the Mapleprimes inline renderer.)

ss1:=-2:  ss2:=1/2:  ss3:=-5:

 

print(`The 3 equations in A, B, C for`*s=ss1,s=ss2,`and `*cat(s,`=`,ss3,` :`));

`The 3 equations in A, B, C for`*s = -2, s = 1/2, `and `*`s=-5 :`

 

Or if you prefer an upright font for the words,

 

Typesetting:-mn(`The 3 equations in A, B, C for`)*s=ss1, s=ss2,
Typesetting:-mn(`and `)*cat(s,`=`,ss3,` :`);

Typesetting:-mn(`The 3 equations in A, B, C for`)*s = -2, s = 1/2, Typesetting:-mn(`and `)*`s=-5 :`

 


Download sent.mw

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