acer

32597 Reputation

29 Badges

20 years, 41 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

I often find that it's more convenient to use so-called 2-argument eval than to use assign on the fsolve result, because the former allows you to immediately do further symbolic computations with the original variables.

But if you do the assign then you'd have to call unassign if you wanted to do further symbolic work with the original variable names.

The appeal of using assign is that formulas involving the names will get the numeric values directly.

Which approach you choose is up to you. Neither is incorrect. Which one is more convenient for you depends on what kind of further work you intend on doing.

restart;
eqs := [c + d = 520.9447091, c - b = 0.04148708484,
        d*a + c + b = 0.04147082666, b - c - d*a = -0.04148773634]:

res := fsolve(eqs);

                                                    -5                                      -8
     res := {c = 0.04147863000, b = -0.8454840000 10  , d = 520.9032305, a = 0.1250712151 10  }

assign(res);

sin(d) + c/b;

                     -4906.469192

cos(d) + b/a;

                     -6759.195990

unassign('a','b','c','d');

# Now you can do further work with the names as symbols.
fsolve( sin(d) = d - 0.5 );

                      1.497300389

# But now the formula doesn't immediately produce a numeric result.
cos(d) + b/a;

                     cos(d) + b/a

eval( cos(d) + b/a, res);

                     -6759.195990

And here is an alternate approach.

restart;

eqs := [c + d = 520.9447091, c - b = 0.04148708484,
        d*a + c + b = 0.04147082666, b - c - d*a = -0.04148773634]:

res := fsolve(eqs);

                                -8                                                          -5
     res := {a = 0.1250712151 10  , c = 0.04147863000, d = 520.9032305, b = -0.8454840000 10  }

eval( sin(d) + c/b, res );

                     -4906.469192

eval( cos(d) + b/a, res );

                     -6759.195990

fsolve( sin(d) = d - 0.5 );

                      1.497300389

cos(d) + b/a;

                      cos(d) + b/a

eval( cos(d) + b/a, res);

                      -6759.195990

You can approach this using operators and D, or expressions and diff. But note that neither will produce ten correct significant digits in the answer if you just use the default working precision of Digits=10.

Increasing the working precision can produce the desired result. But it's not any kind of proof.

restart;

f := 2*sin(x^2/2)-sin(1*x/2)^2:
df := diff(f,x):
dff := diff(f,x,x):

Digits := 20;
                          Digits := 20

r := fsolve(df, x=1..2);
                   r := 1.6870521236466276364

a := eval(dff, x=r);
                  a := -5.2779215898752826466

ans := evalf[10](a);
                      ans := -5.277921590

That may be adequate for you. Using Maple to try and prove correctness of an answer to this question is an interesting task, though it might be out of scope for you.

Two interesting aspects are: how accurate does r have to be such that substitution into the second derivative can robustly produce a result correct to ten significant digits, and what working precision might be needed for that substitution.

Even considering alone the second of those aspects is not basic.

restart;
f := 2*sin(x^2/2)-sin(1*x/2)^2:
df := diff(f,x):
dff := diff(f,x,x):
Digits := 40;
                          Digits := 40

r := fsolve(df, x=1..2);
         r := 1.687052123646627636437294496471862263832

for d from 10 to 20 do
  forget(evalf);
  Digits := d;
  s := shake(subs(x=r, dff));
  a := evalf[2*d]((op([1,2],s) + op([1,1],s))/2);
  t := evalf[2*d](op([1,2],s) - op([1,1],s));
  g := length(trunc(abs(a))) + floor(abs((log10(frac(abs(t))))));
  print(evalf[10](a), t);
  if g >= 10 then
    ans := evalf[10](a);
    break;
  end if;
end do:
                                          -8
                    -5.277921592, 2.255 10  
                                          -9
                    -5.277921589, 2.256 10  
                                         -10
                   -5.277921590, 2.257 10   

ans;
                          -5.277921590

Another way to consider the aspects I mentioned might be to successively compute r accurate to d digits, and then construct an INTERVAL(r-10^(-d), r+10^(-d)) and examine what could be done with that.

Note that simply using default Digits=10 working precision need not produce the answer correct to ten significant digits, whether done using operators or expressions. But both approaches could be used to find the answer correct to ten significant digits.

# Kitonum's suggestion
restart;
f := x->2*sin(x^2/2)-sin(x/2)^2:
x0:=fsolve(D(f)(x)=0, x=1..2);
                   x0 := 1.687052124
(D@@2)(f)(x0);
                      -5.277921591

restart;
f := 2*sin(x^2/2)-sin(x/2)^2:
r:=fsolve(diff(f,x), x=1..2);
                    r := 1.687052124
eval(diff(f,x,x), x=r);
                      -5.277921591

restart;
Digits:=20:
f := x->2*sin(x^2/2)-sin(x/2)^2:
x0:=fsolve(D(f)(x)=0, x=1..2);
                x0 := 1.6870521236466276364
(D@@2)(f)(x0);
                  -5.2779215898752826466
evalf[10](%);
                      -5.277921590
restart;
Digits:=20:
f := 2*sin(x^2/2)-sin(x/2)^2:
r:=fsolve(diff(f,x), x=1..2);
                r := 1.6870521236466276364
eval(diff(f,x,x), x=r);
                  -5.2779215898752826466
evalf[10](%);
                      -5.277921590

One way to do it is by using the plots:-densityplot command. But that can make the Maple GUI behave badly if the grid size is too large. And that allows you to shade the hue by the argument, but doesn't provide any nice mechanism for controlling the intensity or saturation layers.

Instead you can create a color image directly as a 3-dimensional Array.

The following can be made faster, but here I'm focusing on the process.

If you want to get fancy you could try and implement a piecewise structured adjustment to the intensity or saturation layers of the Array (as representing HSV format).

If you increase the grid size (m and n) a great deal then you'll be better off visualizing it with ImageTools:-Embed than with plot and its background option.

restart;

with(ImageTools):

(m,n) := 400, 400;

400, 400

(a,b,c,d) := -3, 3, -3, 3;

-3, 3, -3, 3

M := Array(1..m, 1..n,
           (i,j) -> evalhf( I*(b-(i-1)*(b-a)/(m-1)) + (c+(j-1)*(d-c)/(n-1)) ),
           datatype=complex[8], order=Fortran_order):

f := z -> (z^2-1)*(z-2-I)^2/(z^2+2+2*I);

proc (z) options operator, arrow; (z^2-1)*(z+(-2-I))^2/(z^2+2+2*I) end proc

Z := map[evalhf, inplace](f, copy(M)):

A := Array(1..m, 1..n, 1..3, 1.0, datatype=float[8], order=Fortran_order):

temp := Array(map[evalhf](z->argument(-z), Z), datatype=float[8]):
A[..,..,1] := map[evalhf,inplace](`*`, FitIntensity(temp,inplace), 360):

##
## Some kind of custom adjustment to the Saturation layer of HSV format.
##
#p := 0.0; # 0.01
#A[..,..,2] := FitIntensity(Array(map[evalhf](z->(1-p^abs(z)), Z),
#                                 datatype=float[8]), inplace):

##
## Some kind of custom adjustment to the intensity layer of HSV format.
##
#q := 0.0; # 0.01
#A[..,..,3] := FitIntensity(Array(map[evalhf](z->(1-q^abs(z)), Z),
#                                 datatype=float[8]), inplace):

 

img := HSVtoRGB(A):

plot([[0,0]],x=c..d,y=a..b,axes=boxed,background=img,gridlines=false);

Embed(img);

argument_plot.mw

See also this very old post. But ignore the followup Comments where I added plot axes, since that is done better and more easily in modern Maple by using the background option of the plot command (as I did above).

See also the MathApp accessible in the Help system under the topic ArgumentShading .

For comparison's sake, here is plots:-densityplot on the same example,

restart;

f := z -> (z^2-1)*(z-2-I)^2/(z^2+2+2*I);

proc (z) options operator, arrow; (z^2-1)*(z+(-2-I))^2/(z^2+2+2*I) end proc

plots:-densityplot((x,y)->argument(-f(x+I*y)), -3..3, -3..3, axes=boxed,
                   colorstyle=HUE, style=surface, grid=[351,351]);

density_arg.mw

I could also mention that the color shading data can be pulled out of the plot structure returned by plots:-densityplot, as discussed in this old post.

The keystroke pair Ctl-t switches from math entry mode to text entry mode. That text will appear in black by default.

From text entry mode you can use Ctl-r to switch to active math entry mode, or you can use Shift-F5 to switch to inactive math entry mode.

You can switch back and forth, in order to produce 2D typeset math appearing inlined within a paragraph of text. The active math will get executed (when you hit the !!! icon on the menubar, say) while the inactive math won't get executed.

What you saw in red was 1D Maple Notation (plaintext) math, and not text.

 

 

You could put the values in a Matrix and then export using commands like ExportMatrix or ExcelTools:-Export . No need to copy & paste.

Dummy_5_ac.mw

If you put all the values in a list then you can use the select command to separate out the purely real values. Then you could pick off one of them (the first, or last, possibly after sorting them).

[edit] The first argument passed to select could also test for inclusion within a specific range. Basically, you make the first argument passed to select be a predicate which returns true or false according to some condition of your choice. The third and additional arguments get passed as options to the first argument. See also Kitonum's answer below.

note: The fsolve example below is deliberately artifical. It's just an example. (If you were really using fsolve then you could specify a real range, or drop the complex option, etc.

For example,

restart;

f := a -> fsolve(x^3+a*x+1,x,complex):

f(2.3);

   -0.405741100177881, 0.202870550088940 - 1.55674962029228 I,
   0.202870550088940 + 1.55674962029228 I

sel := a -> select(type,[f(a)],realcons)[1]:

sel(2.3);

               -0.405741100177881

V := Vector(7):
for i from 1 to 7 do
  V[i] := sel(10*sin(i));
end do:

V;

                [-0.118641053844103]
                [                  ]
                [-0.109829320596285]
                [                  ]
                [-0.574354935221908]
                [                  ]
                [-2.81483317335910 ]
                [                  ]
                [-3.14753110820927 ]
                [                  ]
                [-1.82790314819886 ]
                [                  ]
                [-0.151678953479572]

Vector(7, i->sel(10*sin(i)));

                [-0.118641053844103]
                [                  ]
                [-0.109829320596285]
                [                  ]
                [-0.574354935221908]
                [                  ]
                [-2.81483317335910 ]
                [                  ]
                [-3.14753110820927 ]
                [                  ]
                [-1.82790314819886 ]
                [                  ]
                [-0.151678953479572]

For a univariate polynomial (after substituion for B and k) the sorting done under evalf(RootOf(...)) may well interfere with the notion that any single indexed RootOf represents a particular root (whatever than means). So there may not be much additional conceptual harm in allowing fsolve to compute them all and sort them as it does.

This is pretty quick.

restart;

kernelopts(version);

`Maple 12.02, X86 64 LINUX, Dec 10 2008 Build ID 377066`

gm := V -> 1/sqrt(1-V^2):
T := w-k*V:
S := w*V-k:

f := unapply(-135/4*w^5+369/16*w^3*k^2+47/4*I*w^4-93/16*I*w^2*k^2+w^3-2/3*w^3*k*B-27/16*k^4*w+3/16*I*k^4-1/3*w*k^2+2/9*k^3*w*B,w,B,k):

Hgen := simplify(rationalize(f(w, B, k)));

-(135/4)*w^5+(369/16)*w^3*k^2+((47/4)*I)*w^4-((93/16)*I)*w^2*k^2+w^3-(2/3)*w^3*k*B-(27/16)*k^4*w+((3/16)*I)*k^4-(1/3)*w*k^2+(2/9)*k^3*w*B

HHp := proc(kk) option remember, system;
         local res;
         res := fsolve(eval(Hgen,[B=1,k=kk]),w);
       end proc:

HHp(0.5);
Im(HHp(0.5)[1]);

-.3692397178+0.3535761035e-1*I, -.1096424746+0.5462593142e-1*I, .1681810646*I, .1096424746+0.5462593142e-1*I, .3692397178+0.3535761035e-1*I

0.3535761035e-1

opts := thickness=2, symbol=solidcircle, symbolsize=12:

forget(HHp);
st := time():

plt1 := plot(k->Im(HHp(k)[1]), 0..1, color=red, opts):
plt2 := plot(k->Im(HHp(k)[2]), 0..1, color=black, opts):
plt3 := plot(k->Im(HHp(k)[3]), 0..1, color=blue, opts):
plt4 := plot(k->Im(HHp(k)[4]), 0..1, color=gold, style=point, opts):
plt5 := plot(k->Im(HHp(k)[5]), 0..1, color=blue, style=point, opts):

(time()-st)*`seconds`;

.228*seconds

plots:-display(plt5, plt4, plt3, plt2, plt1, gridlines = false);

 

Download file2_acer.mw

And, with option discont=true 

restart;

kernelopts(version);

`Maple 12.02, X86 64 LINUX, Dec 10 2008 Build ID 377066`

gm := V -> 1/sqrt(1-V^2):
T := w-k*V:
S := w*V-k:

f := unapply(-135/4*w^5+369/16*w^3*k^2+47/4*I*w^4-93/16*I*w^2*k^2+w^3-2/3*w^3*k*B-27/16*k^4*w+3/16*I*k^4-1/3*w*k^2+2/9*k^3*w*B,w,B,k):

Hgen := simplify(rationalize(f(w, B, k)));

-(135/4)*w^5+(369/16)*w^3*k^2+((47/4)*I)*w^4-((93/16)*I)*w^2*k^2+w^3-(2/3)*w^3*k*B-(27/16)*k^4*w+((3/16)*I)*k^4-(1/3)*w*k^2+(2/9)*k^3*w*B

HHp := proc(kk) option remember, system;
         local res;
         res := fsolve(eval(Hgen,[B=1,k=kk]),w);
       end proc:

HHp(0.5);
Im(HHp(0.5)[1]);

-.3692397178+0.3535761035e-1*I, -.1096424746+0.5462593142e-1*I, .1681810646*I, .1096424746+0.5462593142e-1*I, .3692397178+0.3535761035e-1*I

0.3535761035e-1

opts := thickness=2, symbol=solidcircle, symbolsize=12, discont=true:

forget(HHp);
st := time():

plt1 := plot(k->Im(HHp(k)[1]), 0..1, color=red, opts):
plt2 := plot(k->Im(HHp(k)[2]), 0..1, color=black, opts):
plt3 := plot(k->Im(HHp(k)[3]), 0..1, color=blue, opts):
plt4 := plot(k->Im(HHp(k)[4]), 0..1, color=gold, style=point, opts):
plt5 := plot(k->Im(HHp(k)[5]), 0..1, color=blue, style=point, opts):

(time()-st)*`seconds`;

4.255*seconds

plots:-display(plt5, plt4, plt3, plt2, plt1, gridlines = false);

 

Download file2_acer_discont.mw

You could regain quite a bit of the original's speed by putting the discont=true option only plt3.  file2_acer_discont_plt3.mw

Suppose that your Matrix has already been assigned to the name M.

Create a new Matrix where entries of M which equal zero are replaced by undefined.

Then call plots:-matrixplot or plots:-surfata on that new Matrix.

newM := map(u->`if`(u=0,undefined,u), M):

plots:-matrixplot(newM);

plots:-surfdata(newM);

 

I'm not really sure what your questions are. Are you looking to get something like this?

restart:

# # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Test of geometry, radical axis.
# # # # # # # # # # # # # # # # # # # # # # # # # # # #

with(geometry):
with(plots):

_EnvHorizontalName := x: _EnvVerticalName := y:

R:=5:

circle(c1,x^2+(y-2*R*cos(Pi/6))^2=R^2):  # 'ctext'=c1):
circle(c2,(x-R)^2+y^2=R^2):
circle(c3,(x+R)^2+y^2=R^2):
RadicalAxis(ra12,c1,c2):
RadicalAxis(ra13,c1,c3):

printf("Colors:  c1=red c2=blue  c3=gold\n");
printf("       ra12=magenta    ra23=grey\n");

Colors:  c1=red c2=blue  c3=gold

       ra12=magenta    ra23=grey

 

t1:=textplot([0, 1.8*R, `Circle c1`]):
t2:=textplot([R, 1.0, `Circle c2`]):
t3:=textplot([-R, 1.0, `Circle c3`]):

if AreTangent(c1,c2) then
   msg1:=sprintf("Circles c1 and c2 are tangential, (as they all are!)\n"):
else
   msg1:="";
end if:

test12:=map(u->`if`(u=0,0,u/content(u)),Equation(ra12)):
sort(test12,order=plex(y,x),ascending):

msg2:=sprintf("Equation of radical axis for c1 & c2 is %A\n",test12):

test13:=map(u->`if`(u=0,0,u/content(u)),Equation(ra13)):
sort(test13,order=plex(y,x),ascending):

msg3:=sprintf("Equation of radical axis for c1 & c3 is %A\n",test13):

display(draw([c1, c2, c3, ra12, ra13],
             color=[red, blue,gold, magenta,grey, black]),
        t1, t2, t3, axes=normal);
printf("%s",msg1);
printf("%s",msg2);
printf("%s\n",msg3);

Circles c1 and c2 are tangential, (as they all are!)
Equation of radical axis for c1 & c2 is 5+x-3^(1/2)*y = 0
Equation of radical axis for c1 & c3 is 5-x-3^(1/2)*y = 0

 

msg2:=sprintf("Equation of radical axis for c1 & c2 is\n %A\n",test12):
msg3:=sprintf("Equation of radical axis for c1 & c3 is\n %A\n",test13):
display(draw([c1, c2, c3, ra12, ra13],
             color=[red, blue,gold, magenta,grey, black]),
        t1, t2, t3,
        caption=cat("\n",msg1,"\n",msg2,"\n",msg3),
        axes=normal);

 

 

simplify_question_ac.mws

It's straightforward to construct re-usable procedures that map CDF and Quantile over z as a list (or Vector, etc), as well as handle scalar z.

I have reversed Maple's usual meaning for the numeric::truefalse option here. So rational inputs are treated with the floating-point method (and exact symbolic handling is allowed by specifying numeric=false).

This isn't restricted to the Normal distribution. You could make XRandomVariable of some other distribution.

restart;

 

cdfmap := proc(R, z::{scalar,list,Vector,Matrix,Array},
               {numeric::truefalse:=true})
         if z::scalar then
           Statistics:-CDF(R,z,':-numeric'=numeric);
         else
           map[2](Statistics:-CDF,R,z,':-numeric'=numeric);
         end if;
       end proc:

invcdfmap := proc(R, z::{scalar,list,Vector,Matrix,Array},
                 {numeric::truefalse:=true})
         if z::scalar then
           map[2](Statistics:-Quantile,R,z,':-numeric'=numeric);
         else
           map[2](Statistics:-Quantile,R,z,':-numeric'=numeric);
         end if;
       end proc:

 

X := Statistics:-RandomVariable(Normal(0,1)):

 

Statistics:-CDF(X, 2.7102);

HFloat(0.9966378676090544)

Statistics:-Quantile(X, Statistics:-CDF(X, 2.7102));

HFloat(2.7102000000012962)

cdfmap(X, 2.7102);

HFloat(0.9966378676090544)

invcdfmap(X, cdfmap(X, 2.7102));

HFloat(2.7102000000012962)

phi := cdfmap(X, [2.7102, 2.2, 1.7]);

[HFloat(0.9966378676090544), HFloat(0.9860965524865014), HFloat(0.955434537241457)]

invcdfmap(X, phi);

[HFloat(2.7102000000012962), HFloat(2.1999999999992075), HFloat(1.7000000000008373)]

cdfmap(X, [27102/10000, 22/10, 17/10]);
invcdfmap(X, %);

[HFloat(0.9966378676090544), HFloat(0.9860965524865014), HFloat(0.955434537241457)]

[HFloat(2.7102000000012962), HFloat(2.1999999999992075), HFloat(1.7000000000008373)]

cdfmap(X, [27102/10000, 22/10, 17/10], numeric=false);

[1/2+(1/2)*erf((13551/10000)*2^(1/2)), 1/2+(1/2)*erf((11/10)*2^(1/2)), 1/2+(1/2)*erf((17/20)*2^(1/2))]

Download cdf_map.mw

[edit] I could also mention that you can also use the elementwise ~ on the CDF and Quantile commands. (One reason I constructed the above procedures is so that the numeric option behavior was reversed, to use floats by default because that might be more Matlab-ish.) You might find this just as easy,

restart;
with(Statistics):

X := RandomVariable(Normal(0,1)):

CDF~(X, [2.7102, 2.2, 1.7]);
   [0.996637867609054, 0.986096552486501, 0.955434537241457]

Quantile~(X, %);
     [2.71020000000130, 2.19999999999921, 1.70000000000084]

CDF(X, 2.7102);
                       0.996637867609054

CDF~(X, 2.7102);
                       0.996637867609054

restart;
with(Statistics):

CDF~(RandomVariable(Normal(0,1)), [2.7102, 2.2, 1.7]);

   [0.996637867609054, 0.986096552486501, 0.955434537241457]

Quantile~(RandomVariable(Normal(0,1)), %);

     [2.71020000000130, 2.19999999999921, 1.70000000000084]

It seems that the solution obtained at lower values of n can provide a useful initial point for a higher value of n.

Below it's done in two ways.

The first uses this bootstrapping approach for values of n=7,13,17,18,19,20.

The second does it in a loop, using all n from 2 to 20. (slower overall, but perhaps more robust!?)

restart

interface(rtablesize = 10)

kernelopts(version)

`Maple 2019.0, X86 64 LINUX, Mar 9 2019, Build ID 1384062`

r[0] := 3.12*10^(-5)

r[1] := 1.00*10^(-4)

r[2] := 1.25*10^(-4)

r[3] := 1.87*10^(-4)

r[4] := 2.50*10^(-4)

e1 := t[0] = (-p[0, fail]^7+1)/((1-p[0, fail])*((-p[0, fail]^7+1)/(1-p[0, fail])+(17/2+(17/2)*p[0, fail]+(33/2)*p[0, fail]^2+(33/2)*p[0, fail]^3+(65/2)*p[0, fail]^4+(65/2)*p[0, fail]^5+(65/2)*p[0, fail]^6)/p[0, idle]+(1-r[0])*(p[0, fail]^6+(-p[0, fail]^6+1)*p[0, succ]/(1-p[0, fail]))/r[0])); e2 := t[1] = (-p[1, fail]^7+1)/((1-p[1, fail])*((-p[1, fail]^7+1)/(1-p[1, fail])+(9/2+(9/2)*p[1, fail]+(17/2)*p[1, fail]^2+(17/2)*p[1, fail]^3+(33/2)*p[1, fail]^4+(33/2)*p[1, fail]^5+(33/2)*p[1, fail]^6)/p[1, idle]+(1-r[1])*(p[1, fail]^6+(-p[1, fail]^6+1)*p[1, succ]/(1-p[1, fail]))/r[1])); e3 := t[2] = (-p[2, fail]^7+1)/((1-p[2, fail])*((-p[2, fail]^7+1)/(1-p[2, fail])+(5/2+(5/2)*p[2, fail]+(9/2)*p[2, fail]^2+(9/2)*p[2, fail]^3+(17/2)*p[2, fail]^4+(17/2)*p[2, fail]^5+(17/2)*p[2, fail]^6)/p[2, idle]+(1-r[2])*(p[2, fail]^6+(-p[2, fail]^6+1)*p[2, succ]/(1-p[2, fail]))/r[2])); e4 := t[3] = (-p[3, fail]^7+1)/((1-p[3, fail])*((-p[3, fail]^7+1)/(1-p[3, fail])+(3/2+(3/2)*p[3, fail]+(5/2)*p[3, fail]^2+(5/2)*p[3, fail]^3+(9/2)*p[3, fail]^4+(9/2)*p[3, fail]^5+(9/2)*p[3, fail]^6)/p[3, idle]+(1-r[3])*(p[3, fail]^6+(-p[3, fail]^6+1)*p[3, succ]/(1-p[3, fail]))/r[3])); e5 := t[4] = (-p[4, fail]^7+1)/((1-p[4, fail])*((-p[4, fail]^7+1)/(1-p[4, fail])+(1+p[4, fail]+(3/2)*p[4, fail]^2+(3/2)*p[4, fail]^3+(5/2)*p[4, fail]^4+(5/2)*p[4, fail]^5+(5/2)*p[4, fail]^6)/p[4, idle]+(1-r[4])*(p[4, fail]^6+(-p[4, fail]^6+1)*p[4, succ]/(1-p[4, fail]))/r[4])); e6 := p[0, fail] = n*t[0]*(1-(1-t[0])^(n-1)*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n)+0.1590000000e-1*n*t[0]*(1-t[0])^(n-1)*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n/(1-(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e7 := p[1, fail] = n*t[1]*(1-(1-t[1])^(n-1)*(1-t[0])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n)+0.1590000000e-1*n*t[1]*(1-t[1])^(n-1)*(1-t[0])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n/(1-(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e8 := p[2, fail] = n*t[2]*(1-(1-t[2])^(n-1)*(1-t[1])^n*(1-t[0])^n*(1-t[3])^n*(1-t[4])^n)+0.1590000000e-1*n*t[2]*(1-t[2])^(n-1)*(1-t[1])^n*(1-t[0])^n*(1-t[3])^n*(1-t[4])^n/(1-(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e9 := p[3, fail] = (1/2)*n*t[3]*(1-(1-t[3])^(n-1)*(1-t[4])^n)+(1/2)*n*t[3]*(1-(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^(n-1)*(1-t[4])^n)+(0.1590000000e-1*((1/2)*n*t[3]*(1-t[3])^(n-1)*(1-t[4])^n+(1/2)*n*t[3]*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^(n-1)*(1-t[4])^n))/(1-(1/2)*(1-t[3])^n*(1-t[4])^n-(1/2)*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e10 := p[4, fail] = (1/2)*n*t[4]*(1-(1-t[4])^(n-1)*(1-t[3])^n)+(1/2)*n*t[4]*(1-(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[4])^(n-1)*(1-t[3])^n)+(0.1590000000e-1*((1/2)*n*t[4]*(1-t[4])^(n-1)*(1-t[3])^n+(1/2)*n*t[4]*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[4])^(n-1)*(1-t[3])^n))/(1-(1/2)*(1-t[3])^n*(1-t[4])^n-(1/2)*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e11 := p[0, succ] = .9841000000*n*t[0]*(1-t[0])^(n-1)*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n/(1-(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e12 := p[1, succ] = .9841000000*n*t[1]*(1-t[1])^(n-1)*(1-t[0])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n/(1-(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e13 := p[2, succ] = .9841000000*n*t[2]*(1-t[2])^(n-1)*(1-t[1])^n*(1-t[0])^n*(1-t[3])^n*(1-t[4])^n/(1-(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e14 := p[3, succ] = (.9841000000*((1/2)*n*t[3]*(1-t[3])^(n-1)*(1-t[4])^n+(1/2)*n*t[3]*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^(n-1)*(1-t[4])^n))/(1-(1/2)*(1-t[3])^n*(1-t[4])^n-(1/2)*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e15 := p[4, succ] = (.9841000000*((1/2)*n*t[4]*(1-t[4])^(n-1)*(1-t[3])^n+(1/2)*n*t[4]*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[4])^(n-1)*(1-t[3])^n))/(1-(1/2)*(1-t[3])^n*(1-t[4])^n-(1/2)*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^n*(1-t[4])^n); e16 := p[0, idle] = (1-t[0])^(n-1)*(1-t[1])^n*(1-t[2])^n; e17 := p[1, idle] = (1-t[1])^(n-1)*(1-t[0])^n*(1-t[2])^n; e18 := p[2, idle] = (1-t[2])^(n-1)*(1-t[1])^n*(1-t[0])^n; e19 := p[3, idle] = (1/2)*(1-t[3])^(n-1)*(1-t[4])^n+(1/2)*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[3])^(n-1)*(1-t[4])^n; e20 := p[4, idle] = (1/2)*(1-t[4])^(n-1)*(1-t[3])^n+(1/2)*(1-t[0])^n*(1-t[1])^n*(1-t[2])^n*(1-t[4])^(n-1)*(1-t[3])^n

sys := [seq(eval(cat(e, i)), i = 1 .. 20)]

conds:=map(`=`,indets(sys,And(name,Non(constant))) minus {n},0..1);

{p[0, fail] = 0 .. 1, p[0, idle] = 0 .. 1, p[0, succ] = 0 .. 1, p[1, fail] = 0 .. 1, p[1, idle] = 0 .. 1, p[1, succ] = 0 .. 1, p[2, fail] = 0 .. 1, p[2, idle] = 0 .. 1, p[2, succ] = 0 .. 1, p[3, fail] = 0 .. 1, p[3, idle] = 0 .. 1, p[3, succ] = 0 .. 1, p[4, fail] = 0 .. 1, p[4, idle] = 0 .. 1, p[4, succ] = 0 .. 1, t[0] = 0 .. 1, t[1] = 0 .. 1, t[2] = 0 .. 1, t[3] = 0 .. 1, t[4] = 0 .. 1}

sol[7] := fsolve(eval(sys, n = 7), conds);

{p[0, fail] = 0.1725732060e-2, p[0, idle] = .9903415166, p[0, succ] = .1043549027, p[1, fail] = 0.3088989313e-2, p[1, idle] = .9905749067, p[1, succ] = .1868442149, p[2, fail] = 0.3454963251e-2, p[2, idle] = .9906375843, p[2, succ] = .2089969336, p[3, fail] = 0.4860178835e-2, p[3, idle] = .9862434767, p[3, succ] = .2970648958, p[4, fail] = 0.5619842175e-2, p[4, idle] = .9863404432, p[4, succ] = .3435277781, t[0] = 0.2981348398e-3, t[1] = 0.5336754095e-3, t[2] = 0.5969115356e-3, t[3] = 0.6286120788e-3, t[4] = 0.7268596334e-3}

sol[13] := fsolve(eval(sys, n = 13), sol[7], conds);

{p[0, fail] = 0.1811745261e-2, p[0, idle] = .9817474126, p[0, succ] = .1035504405, p[1, fail] = 0.3242216921e-2, p[1, idle] = .9819805650, p[1, succ] = .1854040568, p[2, fail] = 0.3626151289e-2, p[2, idle] = .9820431831, p[2, succ] = .2073876078, p[3, fail] = 0.4984792186e-2, p[3, idle] = .9739267569, p[3, succ] = .2952561294, p[4, fail] = 0.5763517604e-2, p[4, idle] = .9740230984, p[4, succ] = .3414368147, t[0] = 0.3004375377e-3, t[1] = 0.5377969671e-3, t[2] = 0.6015257528e-3, t[3] = 0.6324491804e-3, t[4] = 0.7312975182e-3}

sol[17] := fsolve(eval(sys, n = 17), sol[13], conds);

{p[0, fail] = 0.1902958391e-2, p[0, idle] = .9759851872, p[0, succ] = .1030103109, p[1, fail] = 0.3405000403e-2, p[1, idle] = .9762181798, p[1, succ] = .1844371111, p[2, fail] = 0.3808095785e-2, p[2, idle] = .9762807580, p[2, succ] = .2063070876, p[3, fail] = 0.5120884499e-2, p[3, idle] = .9657202245, p[3, succ] = .2940419271, p[4, fail] = 0.5920604827e-2, p[4, idle] = .9658161483, p[4, succ] = .3400331814, t[0] = 0.3020036099e-3, t[1] = 0.5406000512e-3, t[2] = 0.6046639560e-3, t[3] = 0.6350512932e-3, t[4] = 0.7343070663e-3}

sol[18] := fsolve(eval(sys, n = 18), sol[17], conds);

{p[0, fail] = 0.1930046058e-2, p[0, idle] = .9745404430, p[0, succ] = .1028747923, p[1, fail] = 0.3453365646e-2, p[1, idle] = .9747733954, p[1, succ] = .1841945044, p[2, fail] = 0.3862160540e-2, p[2, idle] = .9748359636, p[2, succ] = .2060359860, p[3, fail] = 0.5161607349e-2, p[3, idle] = .9636691261, p[3, succ] = .2937373132, p[4, fail] = 0.5967623643e-2, p[4, idle] = .9637649452, p[4, succ] = .3396810444, t[0] = 0.3023990953e-3, t[1] = 0.5413079232e-3, t[2] = 0.6054564644e-3, t[3] = 0.6357074542e-3, t[4] = 0.7350659702e-3}

sol[19] := fsolve(eval(sys, n = 19), sol[18], conds);

{p[0, fail] = 0.1958858820e-2, p[0, idle] = .9730940045, p[0, succ] = .1027390773, p[1, fail] = 0.3504818935e-2, p[1, idle] = .9733269167, p[1, succ] = .1839515461, p[2, fail] = 0.3919679479e-2, p[2, idle] = .9733894748, p[2, succ] = .2057644920, p[3, fail] = 0.5205026377e-2, p[3, idle] = .9616182321, p[3, succ] = .2934322698, p[4, fail] = 0.6017760081e-2, p[4, idle] = .9617139466, p[4, succ] = .3393284112, t[0] = 0.3027961900e-3, t[1] = 0.5420186757e-3, t[2] = 0.6062522009e-3, t[3] = 0.6363658969e-3, t[4] = 0.7358275140e-3}

sol[20] := fsolve(eval(sys, n = 20), sol[19], conds);

{p[0, fail] = 0.1989402444e-2, p[0, idle] = .9716458621, p[0, succ] = .1026031649, p[1, fail] = 0.3559370593e-2, p[1, idle] = .9718787340, p[1, succ] = .1837082346, p[2, fail] = 0.3980664162e-2, p[2, idle] = .9719412822, p[2, succ] = .2054926035, p[3, fail] = 0.5251149844e-2, p[3, idle] = .9595675377, p[3, succ] = .2931267948, p[4, fail] = 0.6071023693e-2, p[4, idle] = .9596631475, p[4, succ] = .3389752792, t[0] = 0.3031949056e-3, t[1] = 0.5427323292e-3, t[2] = 0.6070511885e-3, t[3] = 0.6370266357e-3, t[4] = 0.7365917143e-3}

eval( eval(map(lhs-rhs,sys), n=20), sol[20] );

[0., 0., 0., -0.2e-12, 0.3e-12, -0.35e-10, -0.65e-10, -0.75e-10, -0.129e-9, -0.148e-9, -0.29e-8, -0.49e-8, -0.57e-8, -0.88e-8, -0.103e-7, -0.6e-9, -0.5e-9, -0.4e-9, -0.11e-8, -0.12e-8]

#
# Automating it, but incrementing n by only 1 each iteration.
#
S[2] := fsolve(eval(sys, n = 2), conds):
for i from 3 to 20 do
  st := time();
  S[i] := fsolve(eval(sys, n = i), S[i-1], conds);
  elapsed := time()-st;
  if type(eval(S[i],1), 'specfunc(fsolve)') then
    print("failed at i=%1",i);
  else
    print(sprintf("succeeded at i=%a in %a seconds",i,elapsed));
  end if;
end do:

"succeeded at i=3 in .72e-1 seconds"

"succeeded at i=4 in .81e-1 seconds"

"succeeded at i=5 in .100 seconds"

"succeeded at i=6 in .141 seconds"

"succeeded at i=7 in .234 seconds"

"succeeded at i=8 in 1.525 seconds"

"succeeded at i=9 in .537 seconds"

"succeeded at i=10 in .839 seconds"

"succeeded at i=11 in 1.271 seconds"

"succeeded at i=12 in 1.867 seconds"

"succeeded at i=13 in 2.681 seconds"

"succeeded at i=14 in 3.874 seconds"

"succeeded at i=15 in 5.707 seconds"

"succeeded at i=16 in 9.394 seconds"

"succeeded at i=17 in 9.906 seconds"

"succeeded at i=18 in 17.662 seconds"

"succeeded at i=19 in 23.167 seconds"

"succeeded at i=20 in 36.280 seconds"

S[20];

{p[0, fail] = 0.1989402444e-2, p[0, idle] = .9716458621, p[0, succ] = .1026031649, p[1, fail] = 0.3559370593e-2, p[1, idle] = .9718787340, p[1, succ] = .1837082346, p[2, fail] = 0.3980664162e-2, p[2, idle] = .9719412822, p[2, succ] = .2054926035, p[3, fail] = 0.5251149844e-2, p[3, idle] = .9595675377, p[3, succ] = .2931267948, p[4, fail] = 0.6071023693e-2, p[4, idle] = .9596631475, p[4, succ] = .3389752792, t[0] = 0.3031949056e-3, t[1] = 0.5427323292e-3, t[2] = 0.6070511885e-3, t[3] = 0.6370266357e-3, t[4] = 0.7365917143e-3}

eval( eval(map(lhs-rhs,sys), n=20), S[20] );

[0., 0., 0., -0.2e-12, 0.3e-12, -0.35e-10, -0.65e-10, -0.75e-10, -0.129e-9, -0.148e-9, -0.29e-8, -0.49e-8, -0.57e-8, -0.88e-8, -0.103e-7, -0.6e-9, -0.5e-9, -0.4e-9, -0.11e-8, -0.12e-8]

 

 

Download solveSYS_ac.mw

If we plot the values for each variable, in the solution as n changes, we might observe that all the curves appear linear except for p[j,fail] , j=1..4, which are monotomic and could be interpolated. I would guess that reasonably close initial points could be generated for the higher n, based on a smaller number of the solutions for lower n (which compute more quickly).
solveSYS_ac2.mw
I would not be surprised if symbolic examination of the equations could lead to a non-numeric or hybrid symbolic-numeric approach where the solutions (dependent on n) were constructed very quickly. I don't have time for that.

restart;

Digits := 12;

12

ee := (-69/50)*sin((32/25)*x) = (4/5)*exp((-23/50)*x):
 

rts := Student:-Calculus1:-Roots(ee, x=0..10, numeric);

[2.59251746013, 4.86028632939, 7.37831403654, 9.81251449999]

evalf[10](rts[1]);

2.592517460

# another way
RootFinding:-NextZero(unapply((lhs-rhs)(ee),x), 0.0);
evalf[10](%);

2.59251746013

2.592517460

Download nz.mw

It turns out that increasing Digits up front may not be necessary here. But I include it anyway, since it may give you an idea in the future.

The help page for parse describes that the offset option can be supplied alongside the statement option, and that the lastread option allows for a running update to a specified name to hold the position least read.

Doing that in a loop allows for multiple statements to be parsed from a single string. Or you can construct a procedure to execute such a loop.

That is more robust than simply splitting the string at colons and/or semicolons, since those could appear in locations where the parsing should not be split.

An extra choice is to try and discern (and return) information about what (previously unassigned) names might have been newly assigned by this process. I realize that this may be of less relevance to your purpose, since your script that constructs the strings likely already knows to what names it will assign.

restart;

#
# This technique works even if the statement separators
# include a mix of colon and semicolon.
#
# It also works if colon or semicolon appears in places other
# than as statement separators.
#
# Since this use of `anames(user)` only detect assignments to
# names which were not yet assigned you may choose to have
# the procedure return NULL and get rid of the anames stuff.
#

parseall:=proc(s::string)
  local res, n, A, temp;
  A := {anames(':-user')};
  n:=0; res := [];
  while n<length(s) do
    temp := parse(s,':-lastread'='n',':-offset'=n,':-statement');
    res := [res[],[{anames(':-user')} minus A,eval(temp,1)]];
    A := {anames(':-user')};
  end do;
  res;
end proc:

 

data1 := "x:='x';y:='y';sol:=dsolve(diff(y(x),x)=1,y(x));":

out := parseall(data1);

[[{}, x], [{}, y], [{sol}, y(x) = x+_C1]]

x,y,sol;

x, y, y(x) = x+_C1

# What names were just newly assigned?
map[2](op,1,eval(out,1));

[{}, {}, {sol}]

data2 := "x:='x':f:=proc(a::integer) a^2; end proc;y:='y':`g;h`;sol:=dsolve(diff(y(x),x)=1,y(x));":

out := parseall(data2);

[[{}, x], [{f}, proc (a::integer) a^2 end proc], [{}, y], [{}, `g;h`], [{}, y(x) = x+_C1]]

x,y,sol;

x, y, y(x) = x+_C1

# What names were just newly assigned?
# Notice that `sol` was already assigned, so didn't show up.
map[2](op,1,eval(out,1));

[{}, {f}, {}, {}, {}]

sol := 'sol': f := 'f':
out := parseall(data2);

[[{}, x], [{f}, proc (a::integer) a^2 end proc], [{}, y], [{}, `g;h`], [{sol}, y(x) = x+_C1]]

# What names were just newly assigned?
map[2](op,1,eval(out,1));

[{}, {f}, {}, {}, {sol}]

# This first example succeeds, by splitting the string.
# There is no indication of what was assigned.
#
eval~(parse~(StringTools:-Split(data1, ";")));

[x, y, y(x) = x+_C1]

# This example fails, by splitting the string. It does not
# correctly interpret colons and semicolons used within
# procedures as statement separators. It also does not
# correctly interpret colons and semicolons appearing other
# than as statement separators.
#
eval~(parse~(StringTools:-Split(data2, ";")));

Warning, extra characters at end of parsed string

Error, incorrect syntax in parse: reserved word `end` unexpected (near 4th character of parsed string)

map(lprint, StringTools:-Split(data2, ";")):

"x:='x':f:=proc(a::integer) a^2"
" end proc"
"y:='y':`g"
"h`"
"sol:=dsolve(diff(y(x),x)=1,y(x))"
""

Download parsestatements.mw

By "newly assigned" I mean unassigned before the call. I don't mean re-assigned.

The error message describes the situation: the Int call is not supported by evalhf.

Did you just want to make it faster? Note that the quadrature scheme can utilize evalhf for the evaluations of the integrand.

restart; f1 := proc (XX::Array) local GG, i; GG := 0; for i to 500 do GG := GG+Int(z^2/(1000*XX[i]-z)^2, z = 0 .. 100) end do; return GG end proc; A1 := Array(1 .. 500, [seq(-i^2+100-1, i = 1 .. 500)]); CodeTools:-Usage(evalf(f1(A1)))

memory used=34.63MiB, alloc change=6.01MiB, cpu time=180.00ms, real time=188.00ms, gc time=12.68ms

.2915102677

restart; f1 := proc (XX::Array) local i; add(evalf(Int(z^2/(1000*XX[i]-z)^2, z = 0 .. 100, method = _d01ajc)), i = 1 .. 500) end proc; A1 := Array(1 .. 500, [seq(-i^2+100-1, i = 1 .. 500)]); CodeTools:-Usage(f1(A1))

memory used=13.34MiB, alloc change=2.00MiB, cpu time=73.00ms, real time=81.00ms, gc time=0ns

.2915102681

infolevel[`evalf/int`] := 2; forget(evalf); evalf(Int(z^2/(1000*A1[2]-z)^2, z = 0 .. 100, method = _d01ajc)); infolevel[`evalf/int`] := 0

2

evalf/int/control: integrating on 0 .. 100 the integrand

z^2/(95000-z)^2

Control: Entering NAGInt
trying d01ajc (nag_1d_quad_gen)
d01ajc: trying evalhf callbacks
d01ajc: result=.369928326560882854e-4
d01ajc: abserr=.205351472804473049e-18; num_subint=1; fun_count=21
result=.369928326560882854e-4

0.3699283266e-4

0

 

Download evalhf_int_ac.mw

Or do you have other computations to go inside procedure f1, which you also want done under evalhf?

The subs command does syntactic substituion without evaluation (unless the command name is indexed by the key eval).

The eval command does a more mathematical substitution, in the sense that it has additional knowledge of the mathematics germane to some substitutions.

Often the two produce the same result. Sometimes one specifically wants to avoid evaluation prior to being able to do subsequent manipulations of the result.

Sometimes subs is a bit faster. Relying on that only makes sense up to the situations where one doesn't need the mathematical knowledge.

subs(x=1.2, sin(x));
                         sin(1.2)

subs[eval](x=1.2, sin(x));
                       0.9320390860

eval(sin(x), x=1.2);
                       0.9320390860

There are also differences in how substitutions are done. The subs command allows you to do them together or in sequence. Eg,

subs([a=b,b=c], [a,b]);
                          [b, c]

subs(a=b,b=c, [a,b]);
                          [c, c]

subs(b=c,a=b, [a,b]);
                          [b, c]

eval([a,b], [a=b,b=c]);
                          [b, c]

I'm not sure which aspects are most relevant to your query. There are other subtleties or examples which might interest you.

First 158 159 160 161 162 163 164 Last Page 160 of 339