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

restart

p := proc (S) options operator, arrow; .32*exp(S)/(1.2+1.901885*exp(S)-S^3) end proc

eta := proc (S) options operator, arrow; (D(p))(S)*S/p(S) end proc

assume(k > 0)

f := proc (k) options operator, arrow; A*k^alpha end proc

w := proc (k) options operator, arrow; f(k)-(D(f))(k)*k end proc

beta := 1

A := 28

alpha := .33

chi := proc (i) options operator, arrow; i*((1+beta)/beta+eta(i))/(1+eta(i)) end proc

H := proc (k, i) options operator, arrow; chi(i)-w(k) = 0 end proc

str := time[real](); Praw := plots:-implicitplot(H(k, i), k = 1 .. 2, i = 3 .. 15); (time[real]()-str)*'seconds'

0.53e-1*seconds

transf := plottools:-transform(proc (x, y) options operator, arrow; [x, ln((w(x)-y)*(A*alpha)^beta*(p(y)*y)^(alpha*beta))] end proc)

transf(Praw)

NULL

Download Worksheet_1_implicit_acc.mw

You might also consider applying the print command to the procedure.

In recent versions you could also utilize fprintf with a new format to write out procedures with nice formatting and line-breaks. [edited] See Comment below for an example.

The text version does a step like,

  gen := (i, j) -> evalf(a(inits[j], i))

whereas your version does that like,

   gen := (i, j) -> evalf(a(inits, i))

Those are not the same. And that seems the central mistake.

In this attachment I also changed the call of evalf[4](...), slightly, so that the results are rounded to four digits while still computed at Digits=10 precision. It doesn't make a difference in this example, but using evalf[4] alone is unnecessarily innacurate in general; using that alone is not a great way to simply round results to four digits.

I also inserted an unassignment to name `a`  -- after it was assigned an operator earlier on, and before a subsequent rsolve call. (I had already done this earlier, but have now edited my Answer to mention it.)

Discrete_Dynamical_Models_2_ac.mw

restart

DDS := a(n+1) = (1+.12*(1/12))*a(n)+1000

a(n+1) = 1.010000000*a(n)+1000

rsolve({DDS, a(0) = 0}, a(n)); a := unapply(%, n)

proc (n) options operator, arrow; -100000+100000*(101/100)^n end proc

plot([-100000+100000*(101/100)^n], n = 0 .. 100, a = 0 .. 200000)

pts := {seq([k, a(k)], k = 0 .. 24)}; plot(pts, style = point, title = "Savings Account with Monthly Deposit")

a := 'a'; rsolve({a(0) = 497.5124378, a(n+1) = -1.01*a(n)+1000}, a(n))

a

-(11/1005000000)*(-101/100)^n+100000/201

plot([-(11/1005000000)*(-101/100)^n+100000/201], n = 0 .. 20, a = 0 .. 1000)

solve(ev = -1.01*ev+1000, ev)

497.5124378

rsolve({a(n+1) = .5*a(n)+16}, a(n))

a(0)*(1/2)^n-32*(1/2)^n+32

rsolve({a(0) = 10, a(n+1) = .5*a(n)+16}, a(n))

-22*(1/2)^n+32

smartplot(-22*(1/2)^n+32)

rsolve({a(0) = 20, a(n+1) = .5*a(n)+16}, a(n))

-12*(1/2)^n+32

smartplot(-12*(1/2)^n+32)

rsolve({a(0) = 32, a(n+1) = .5*a(n)+16}, a(n))

32

rsolve({a(0) = 50, a(n+1) = .5*a(n)+16}, a(n))

18*(1/2)^n+32

smartplot(18*(1/2)^n+32)

solve(ev = .5*ev+16, ev)

32.

solve(ev = .5*ev+64, ev)

128.

rsolve({a(0) = A, a(n+1) = .5*a(n)+64}, a(n)); a := unapply(%, [A, n])

A*(1/2)^n-128*(1/2)^n+128

proc (A, n) options operator, arrow; A*(1/2)^n-128*(1/2)^n+128 end proc

inits := [0, 50, 100, 150, 200]

gen := proc (i, j) options operator, arrow; evalf[4](evalf[10](a(inits[j], i))) end proc

proc (i, j) options operator, arrow; evalf[4](evalf[10](a(inits[j], i))) end proc

DrugConcTable := Matrix(10, 5, gen)

Matrix(%id = 18446884047296012030)

 

ps. I also changed your Post into a Question.

If you omit both an explicit multiplication symbol as well as an intervening space then in 2D Input (in Maple 2017) the second brackets will get parsed as a function call.

In Maple the syntax allows for an addition or subtraction of the operator names. Eg,

   (sin + cos)(x)

gets parsed as  sin + cos  applied to argument x, and evaluates to sin(x) + cos(x) .

Also, a number (such as 11) applied to an argument evaluates to just 11 itself.

And so,

   (epsilon[3] - 1)( ... something ...)

gets parsed as  epsilon[3] - 1  applied to that something as argument. It gets parsed as a function call. And it evaluates to  -1  plus  epsilon[3] applied to that something.

This appears to be what has happened in your example, judging by your attachment.

If you do not like to see the explicit "dot" in the 2D Input then you could put a space between such brackets instead, in your Maple 2017. You can control whether such a space gets interpreted implicitly as multiplication as a user preference. See Tools->Options->Interface from the main menubar.

Using rsolve we can obtain exact formula for a[n] and b[n], and giving limit a reasonable helping assumption we can show both have limit sqrt(a[0],b[0]).

The formula N(n)=a*b/M(n) follows from the original pair of formulas. It can be used to remove either M(n) or N(n) from each recurrence relationship obtained from each of the two formulas.

I am naming things as M(n),N(n),a,b  but you could as easily name them a(n),b(n),a0,b0 respectively.

restart;

 

Note:  N(n)=a*b/M(n)

 

GMe := rsolve({M(n)=(M(n-1)+a*b/M(n-1))/2, M(0)=a}, M(n));

(a*b)^(1/2)*coth(arccoth(a/(a*b)^(1/2))*2^n)

limit(GMe, n=infinity) assuming arccoth(a/sqrt(a*b))>0;

(a*b)^(1/2)

GNe := rsolve({N(n)=2*a*b/(a*b/N(n-1)+N(n-1)), N(0)=b}, N(n));

(a*b)^(1/2)*tanh(arctanh(b/(a*b)^(1/2))*2^n)

limit(GNe, n=infinity) assuming arctanh(b/sqrt(a*b))>0;

(a*b)^(1/2)

 

Download recur_fun.mw

If you wish to generate numeric results (exact, or floats) for some concrete pain of initial values a,b then you could pass rsolve its makeproc option, or convert those arctrigh results to expln so as to avoid small imaginary artefacts.

For example, using the above formulas GMe and GNe above for a[n] and b[n],

seq(simplify(eval(convert([GMe,GNe],expln),
                       [a=1,b=2])),
         n=0..4);

             [3  4]  [17  24]  [577  816]  [665857  941664]
     [1, 2], [-, -], [--, --], [---, ---], [------, ------]
             [2  3]  [12  17]  [408  577]  [470832  665857]

evalf([%])[];

    [1., 2.], [1.500000000, 1.333333333],
    [1.416666667, 1.411764706], [1.414215686, 1.414211438],
    [1.414213562, 1.414213562]

Those agree with the float values that vv obtained purely numerically.

There was a corruped, unclosed <Equation> in the XML (raw text of the .mw file).

Closing that up I get the following: see attached. Please check that it contains (almost all) you expect.

The missing equation is an input, likely a few lines after the text, "So, the answer introduced lines above becomes:".

MyMinitCourseComputerAlgebraForPhysicsPart2_ac.zip

It is a shame that the GUI itself cannot recover your worksheet, while it can be done manually with an external text-editor.

Use the * key (shift-8 on my keyboard) for normal multiplication, not the lower-dot which denotes noncommutative multiplication.

If I rerun your attachment then I get a NULL result from solve. But after I change the lower-dots (periods) to * then your worksheet behaves as follows.

restart

kernelopts(version);

with(LinearAlgebra)

`Maple 18.02, X86 64 LINUX, Oct 20 2014, Build ID 991181`

eq1 := Ef*epsilon+B*sinh(Typesetting:-delayDotProduct(eta, z)/rf)+Dd*cosh(Typesetting:-delayDotProduct(eta, z)/rf)

Ef*epsilon+B*sinh((eta.z)/rf)+Dd*cosh((eta.z)/rf)

eq2 := subs({z = l}, eq1) = 0;

Ef*epsilon+B*sinh((eta.l)/rf)+Dd*cosh((eta.l)/rf) = 0

eq3 := subs({z = -l}, eq1) = 0;

Ef*epsilon+B*sinh((eta.(-l))/rf)+Dd*cosh((eta.(-l))/rf) = 0

sol1 := solve({eq2, eq3}, {B, Dd});

{B = 0, Dd = -Ef*epsilon/cosh((eta.l)/rf)}

NULL

Download mapletrial_ac.mw

Your attachment was last saved in Maple 18, so I marked your Question accordingly.

Augmenting a list in a loop (as you did as the later stage of your procedure, to create primelist) is inefficient. You could use seq instead, to run through L.

Consider:

restart;
Eratosthenes := proc(N::posint) 
local L, primeslist, n, k; 
description "Calculate all primes less than or equal to N"; 
L := Array(2 .. N, i->true); 
for n from 2 to trunc(sqrt(N)) do 
if L[n] = true then 
for k from n while k*n <= N do 
L[k*n] := false od; fi; 
od; 
primeslist := NULL; 
for n from 2 to N do 
if L[n] = true then 
primeslist := primeslist, n fi; 
od; 
primeslist;
end proc:

Eratosthenes(32);

       2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31

CodeTools:-Usage(Eratosthenes(2^20)):
memory used=25.24GiB, alloc change=39.49MiB,
cpu time=35.61s, real time=35.68s, gc time=21.98s

nops([%]);

                82025

restart;
Eratosthenes2 := proc(N::posint) 
local L, n, k; 
description "Calculate all primes less than or equal to N"; 
L := Array(2 .. N, i->true); 
for n from 2 to trunc(sqrt(N)) do 
if L[n] = true then 
for k from n while k*n <= N do 
L[k*n] := false od; fi; 
od; 
seq(`if`(L[n]=true,n,NULL), n=2..N);
end proc:

Eratosthenes2(32);

       2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31

CodeTools:-Usage(Eratosthenes2(2^20)):
memory used=183.78MiB, alloc change=20.00MiB,
cpu time=3.49s,real time=3.50s, gc time=1.54s

nops([%]);

                82025

You might rewrite the first part of your code to use hardware integers and then Compile it, or run it in a inner procedure under evalhf. I haven't done either, but I wouldn't be surprised if you could get a further factor of 5 or more speedup. (It could vary according to the kind of data structure used to return the result: eg. hardware Array or expression sequence/list.)

Your procedure extractxishu contains the command,

    remove(has,i,{p,q})

But the procedure extractxishu has the name p as its parameter. Therefore the "p" inside that call to remove is a reference to the parameter p of the procedure, and not a reference to the name  p that appears inside your polynomial (ie. the polynomial that you pass in to the procedure). That's the fundamental mistake and reason why the "p" appearing in the polynomial is not being removed by the procedure call.

One way you could correct that is by making the "p" inside that call to remove be a reference to the global name p that appears in your polynomials. Eg,

extractxishu:=proc(p)
local i,xishulist,teamlist;
  teamlist:=convert(p,list);
  xishulist:=[];
  for i in teamlist do
    if type(i,`^`) then
      xishulist:=[xishulist[],1];
    else
      xishulist:=[xishulist[],remove(has,i,{:-p,:-q})];
    end if;
  end do:
end proc:

Another simple correction would be to change the name of the procedure's parameter (and the places it gets used, such as the conversion to list), to avoid the collision. That could allow your procedure to still pick up the p and q reference, scoped  from the higher level. I haven't shown that, but it's a simple edit.

Or, you could pass the set of names in as as an additional argument to the procedure. Eg,

extractxishu_alt:=proc(p, varset)
local i,xishulist,teamlist;
  teamlist:=convert(p,list);
  xishulist:=[];
  for i in teamlist do
    if type(i,`^`) then
      xishulist:=[xishulist[],1];
    else
      xishulist:=[xishulist[],remove(has,i,varset)];
    end if;
  end do:
end proc:

extractxishu_alt(eq2, {p,q});

I'm not convinced that your procedure would always produce the result you'd expect, for additional examples, partly because I don't understand all your description. But you've already indicated that you are primarily interested in knowing what went fundamentally wrong with your original, so I've tried to focus on that aspect.

The error comes from premature evaluation of the first argument passed to the plot command, ie.,

funktion(x)
Error, (in funktion) cannot determine if this expression is true or false: 2 < x*Units:-Unit(1/m)

That evaluation is part of Maple's usual evaluation model for procedure calls. The procedure funktion is not set up to deal with the symbolic name x as argument, and it is being called before variable x takes on any numeric plotting values.

Using Maple 2021.1, we can work around that by using the so-called operator form calling sequence of the plot command, eg.

restart;
with(Units[Simple]):
funktion := x -> if 2*Unit('m') < x then 1/x; else 2*Unit('m'); end if:
r1 := 3.0*Unit('m'):
r2 := 6*Unit('m'):

plot(funktion, r1 .. r2);

Normally we could also work around the issue by alternatively: 1) delaying evaluation (single right-ticks around the first argument to plot) or, 2) handling the premature evalution by having the procedure return unevaluated if its first argument if not as expected. Those alternatives are problematic here, because of the way that the plot command currently (Maple 2021.1) handles units. (I've run across that before, and consider that a bug, which I've previously reported. It ought to be able to handle those alternatives just as well as it does the operator calling sequence.)

The result of parse("l") is the global instance of that name, and does not match the local l of your procedure.

So, in your procedure, when loop index j is "l" then dummy1 gets assigned according to the global name l and not according to the local name l.

Here is a simpler procedure to illustrate, without the looping or embedded component references.

restart;

test := proc()
  global G;
  local L;
  G := 3.2;
  L := 5.7;
  print("G", eval(parse("G")), G, :-G);
  print("L", eval(parse("L")), L, :-L);
end proc:

test();

        "G", 3.2, 3.2, 3.2

        "L", L, 5.7, L

L := 99;
                               99
test();

        "G", 3.2, 3.2, 3.2

        "L", 99, 5.7, 99

In my opinion using declared globals in a procedure is generally a poor programming practice. Using parse to turn strings into names -- within a procedure -- is also generally poor a programming practice. I think that these should be avoided where feasible to do so. Even large and involved applications with many embedded components (even a dynamically generated collection of same) can often be programmed without resorting to such technique.

You are encoutering premature evaluation of,
   diff(coeff(5*x+x*y+4*x*y^2,y,k),x)
before k attains its numeric values.

One alternative is to use add instead of sum, where the former has special-evaluation rules that delays the evaluation until k gets the numeric values. I generally prefer that instead of using single right-quotes (uneval quotes) to delay the evaluation, if I'm just trying to add up a finite number of items and not doing actual symbolic summation.

In the example below I replaced xy^2 with x*y^2, for fun.

restart;
c:=proc(P) add(diff(coeff(P,y,k),x),k=1..2);end proc:

c(5*x+x*y+4*x*y^2);

            5

restart;
c:=proc(P) sum('diff(coeff(P,y,k),x)',k=1..2);end proc:

c(5*x+x*y+4*x*y^2);

            5

note. This is a common usage misconception. It is essentially the same underlying issue as in your Question from September 2019.

The output=XML makes the Tabulate command return a call to DocumentTools:-Layout:-Table.  That can be used in other Layout:-Table instances, attaining a nested effect.

Here is a (somewhat uninspired) nested example,

restart;
with(DocumentTools): with(DocumentTools:-Layout):
T1 := Vector(5,i->i):
T2 := Vector(3,i->plot(x^i,x=-1..1,size=[100,100])):
xml1 := Tabulate(T1,output=XML):
xml2 := Tabulate(T2,output=XML):
InsertContent(Worksheet(Table(exterior=none,interior=none,
                              Column()$2, alignment=center,
                              widthmode=pixels, width=200,
                              Row(Cell(xml1),Cell(xml2),
                                  alignment=center)))):

nested_Tabluate_ex.mw

Also, I have seen a few cases where the Tabulate command didn't offer some esoteric finer control that I wanted, and after using output=XML I was able to programmatically adjust the raw result and then embed it using a call like the above, ie.,
   InsertContent(Worksheet(... my_xml ...))
Other related use of output=XML is to be able to save the result to a new .mw file, or to embed the result in a new worksheet tab, eg.,

restart;
with(DocumentTools):
L := [seq(plot(x^i, x=-1..1, labels=["",""],
               size=[200,200]), i=1..3)]:
xml := Layout:-Worksheet(
         Tabulate(L, output=XML,
                  widthmode=pixels, width=600)):
:-Worksheet:-Display(ContentToString(xml));

If I understand your question this might get you started.

In the following attachment I create an appliable module (for minor efficiency, so that the inner proc is not created each time F gets called). But a simpler revision, which still allows reusability wrt the degree and variables, is,

F:=proc(p,varlist,deg)
  map(proc(t,vars) local u,v; u:=coeffs(t, vars, v); [u,v]; end proc,
  select(t->degree(t, varlist)=deg,`if`(p::`+`, [op(p)], [p])),
        varlist); end proc:

P := 14*c^4 + 84*c^3*d + 180*c^2*d^2 + 165*c*d^3 + 55*d^4 + 5*c^3
     + 21*c^2*d + 28*c*d^2 + 12*d^3 + 2*c^2 + 5*c*d + 3*d^2 + c + d + 1:

F(P, [c,d], 3);

     [[    3]  [     2  ]  [       2]  [     3]]
     [[5, c ], [21, c  d], [28, c d ], [12, d ]]

F(P, [c,d], 2);

            [[    2]            [    2]]
            [[2, c ], [5, c d], [3, d ]]

cidea.mw

I supposed that you'd want the coefficients associated with the corresponding terms, hence the returned lists of pairs.

You could also get just the coefficients, though naturally then you wouldn't know which terms contained them. Eg, with P being the polynomial,

map(coeffs,select(t->degree(t,[c,d])=3,
                  `if`(P::`+`,[op(P)],[P])),[c,d]);

          [5, 21, 28, 12]

Your mistake lies in your passing an expression sequence to the CodeGeneration:-Matlab command. That makes that command treat the second argument as if it were an (invalid) option to that command.

The result from solve, for your example, is an expression sequence of two scalar expressions.

To remedy this, you could call Matlab(...) on them separately, or put them into a list before the call, etc.

By the way, it seems that the expressions could be simplified and made more compact.

See attached.

calc_theta_ac.mw

ps. You had your Question marked as "Maple 18" (a version from the year 2014). But your attachment was last saved in Maple 2018, which is a later version. I have adjusted the Questions marking accordingly.

First 82 83 84 85 86 87 88 Last Page 84 of 336