acer

32405 Reputation

29 Badges

19 years, 350 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

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.

If the name begins with an ampersand then the parser will accept its use as a binary infix function call (ie. allow its use as a binary infix operator).

For example,

restart;

`&A` := (a,b)->a^b:

x &A y;

               y
              x 

You don't have to assign anything to &A, to construct the call.

Also, you can also enter the call using prefix form, ie.  `&A`(x,y) , and by default that pretty-prints in the infix form.

The above doesn't allow you to enter your stated, literal example   x A y  as input, without the ampersand. However you can get some interesting effects for pretty-printed output and computation, by using the so-called extension mechanism of some low-level commands. Eg,

restart;
`print/&A` := proc(a,b) uses Typesetting;
                mrow(Typeset(a),
                     mi(" A ",':-fontweight'="bold"),
                     Typeset(b));
              end proc:
`expand/&A` := () -> A(args):
`value/&A` := () -> A(args):

A := (a,b) -> a^b:

foo := sin(x) &A sqrt(y);

expand(foo);
value(foo);

In order to alleviate burden on the GUI plot renderer the result of HeatMap is usually accomplished (internally) by use of a background image.

In Maple 2021.1 the background image is being incorrectly rendered to fill the whole inlined plotting window, instead of (as previously) filling only the area bounded by the axes. (My Maple 2021.0 for Linux does not seem to have the problem, so it might be new to point-release 2021.1.)

Two possible workarounds are (undocumented) forcing of the result as either a collection of polygons or a densityplot.

Those put more burden on the GUI, however (ie. they render more slowly, and can make the GUI response sluggish if the plot is swept-selected or right-click, and in some cases when the sheet is scrolled). Export to PNG format image seems reasonably sharp.

Statistics:-HeatMap(Matrix(128,(i,j)->modp(binomial(i,j),2)),
                    color=["White","Black"],method=polygons,
                    axis[1]=[location=high],axis[2]=[location=low],
                    size=[600,400]);

Statistics:-HeatMap(Matrix(128,(i,j)->1-modp(binomial(128-j+1,i),2)),
                    color=["white","Black"],
                    method=densityplot,style=surface,
                    axis[1]=[location=high,tickmarks=[seq(i=i,i=1..128)]],
                    axis[2]=[location=low,tickmarks=[seq(128-j+1=j,j=1..128)]],
                    axes=frame, size=[600,400]);

Here are some ideas, which might help you get started,

Shane_Kreller_M6_Maple_Assignment_ac.mw

Here is another way, using seq instead of a loop,

Given you initial list assigned to z,

LLq:=iquo(nops(z),26):
LLr:=irem(nops(z),26):
AZ:=parse~([$"A".."Z"]):
ans:=[seq(seq(`if`(i=1,AZ[j],cat(AZ[j],i-1))=z[26*(i-1)+j],j=1..26),i=1..LLq),
      seq(`if`(LLq=0,AZ[j],cat(AZ[j],LLq))=z[26*(LLq)+j],j=1..LLr)];

You might also create AZ with,

AZ:=convert~([$"A".."Z"],name):

Mapleprimes_Label_lists_ac.mw

Naturally, it's also possible to start the LHSs with A1..Z1, etc,

[seq(seq(cat(AZ[j], i) = z[26*(i-1)+j], j = 1 .. 26), i = 1 .. LLq),
 seq(cat(AZ[j], LLq+1) = z[26*LLq+j], j = 1 .. LLr)];
First 83 84 85 86 87 88 89 Last Page 85 of 336