acer

32333 Reputation

29 Badges

19 years, 325 days
Ontario, Canada

Social Networks and Content at Maplesoft.com

MaplePrimes Activity


These are answers submitted by acer

@Markiyan Hirnyk I agree with Carl and Kitonum about the specifics of what's going on in your example.

Given that fsolve does not allow options to control working precision separately from tolerance (for x, or for forward error of g(x)) then if you expect a specific number of correct digits in the result then the problem must be formulated to allow that to happen.

Your originally created piecewise never gets close enough to VP[14]. The piecewise you created has jump dicontinuities and  never gets close enough to VP[14] for any x value to be accepted as a root.

Your original piecewise minus VP[14] never attains a value smaller in absolute value than 1e-7 for any x, unless the expression is evaluated at very low (yes, low) working precision. Eg,

forget(evalf);
evalf[7]( g(0.02612015) - VP[14] );

                                     0.

So Carl and Kitonum are correct in the sense that your originally constructed piecewise does not attain -- closely enough -- some of the VP[i] values for any x value to be taken as a root with say 10 correct digits.

But the problem is that fsolve does not allow one to specify absolute or relative tolerance on x, or a tolerance on f(x). Instead fsolve uses Digits to construct its tolerances internally, and provides no finer control or specification by the user of what close enough means. I believe that it is resonable to object to this narrow behaviour by fsolve; it would be better if tolerances were allowed as separate options, so that acceptance criteria did not just depend on Digits.

With the current way that fsolve accepts a value as being a root, you have two choices: 1) Temporarily increase Digits when forming g, so that acceptable roots exists at your current Digits, or 2) Construct g at your current Digits but note that acceptable roots then exist when the expression is evaluated at low enough Digits.

Note that when you increase Digits just a little, for initially forming the piecewise, the places where problematic jump discontinities cause problems can appear  more relatively severely at x values different than before.

On my 64bit Maple 2015 for Linux a value of Digits=13 for initial construction of the piecewise where the jump discontinuities were insignificant enough that fsolve found 15 roots when Digits=10. On another OS it may be necessary to go higher, for the initial construction to actually have acceptable roots.

I've tried to illustrate some of this below.


restart:

VP := Vector[row](16, {(1) = 10, (2) = 177.9780267, (3) = 355.9560534,
                       (4) = 533.9340801, (5) = 711.9121068, (6) = 889.8901335,
                       (7) = 1067.868160, (8) = 1245.846187, (9) = 1423.824214,
                       (10) = 1601.802240, (11) = 1779.780267, (12) = 1957.758294,
                       (13) = 2135.736320, (14) = 2313.714347, (15) = 2491.692374,
                       (16) = 2669.670400}):

VE := Vector[row](16, {(1) = 5.444193931, (2) = .4793595141, (3) = .3166653569,
                       (4) = .2522053489, (5) = .2123038784, (6) = .1822258228,
                       (7) = .1544240625, (8) = .1277082078, (9) = .1055351619,
                       (10) = 0.8639065510e-1, (11) = 0.6936612570e-1,
                       (12) = 0.5388339810e-1, (13) = 0.3955702170e-1,
                       (14) = 0.2612014630e-1, (15) = 0.1338216460e-1,
                       (16) = 0.1203297900e-2}):

oldDigits,Digits := Digits,10:
#oldDigits,Digits := Digits,13: # this might be adequate to find 15 roots at Digits=10
forget(evalf);
for i to 15 do
  p[i] := VE[i+1] < x and x <= VE[i],
          (VP[i+1]-VP[i])*(x-VE[i])/(VE[i+1]-VE[i])+VP[i] end do:
Digits := oldDigits:
forget(evalf);

g := unapply(piecewise(seq(p[i], i = 1 .. 15)), x):

forget(evalf);
evalf[8]( g(0.026120146) - VP[14] );

                                   0.0001

forget(evalf);
evalf[7]( g(0.02612015) - VP[14] );

                                     0.

for i to 15 do
  forget(evalf);
  print(proc(j) local res;
                res:=fsolve(g(x) = VP[j]);
                if res::numeric then res else j end if;
        end proc(i));
end do;
forget(evalf);

                                 5.444193930
                                0.4793595141
                                0.3166653569
                                      4
                                0.2123038784
                                0.1822258228
                                      7
                                0.1277082078
                                      9
                                0.08639065507
                                     11
                                0.05388339812
                                0.03955702173
                                     14
                                0.01338216464

#eval(g(x);

oldDigits,Digits := Digits,100:
forget(evalf);
plot([VP[14],g(x)], x=0.0261201462..0.0261201464, discont, gridlines=false);
Digits := oldDigits:
forget(evalf);

oldDigits,Digits := Digits,6:
for i to 15 do
  forget(evalf);
  print(proc(j) local res;
                res:=fsolve(g(x) = VP[j]);
                if res::numeric then res else j end if;
        end proc(i)) end do;
Digits := oldDigits:
forget(evalf);

                                   5.44419
                                  0.479360
                                  0.316665
                                  0.252205
                                  0.212304
                                  0.182226
                                  0.154424
                                  0.127708
                                  0.105535
                                  0.0863907
                                  0.0693661
                                  0.0538834
                                  0.0395570
                                  0.0261201
                                  0.0133822

oldDigits,Digits := Digits,12: # still not a good enough construction
forget(evalf);
for i to 15 do
  p[i] := VE[i+1] < x and x <= VE[i],
          (VP[i+1]-VP[i])*(x-VE[i])/(VE[i+1]-VE[i])+VP[i] end do:
Digits := oldDigits:
forget(evalf);

g := unapply(piecewise(seq(p[i], i = 1 .. 15)), x):

for i to 15 do
  forget(evalf);
  print(proc(j) local res;
                res:=fsolve(g(x) = VP[j]);
                if res::numeric then res else j end if;
        end proc(i));
end do;
forget(evalf);

                                 5.444193931
                                0.4793595141
                                0.3166653569
                                0.2522053489
                                0.2123038784
                                0.1822258228
                                0.1544240625
                                0.1277082078
                                0.1055351619
                                0.08639065510
                                     11
                                0.05388339810
                                0.03955702170
                                0.02612014630
                                0.01338216460

oldDigits,Digits := Digits,100:
forget(evalf);
plot([VP[11],g(x)], x=0.69366125699e-1..0.69366125701e-1, discont, gridlines=false);
Digits := oldDigits:
forget(evalf);

oldDigits,Digits := Digits,13: # adequate in 64bit Maple 2015 on Linux
forget(evalf);
for i to 15 do
  p[i] := VE[i+1] < x and x <= VE[i],
          (VP[i+1]-VP[i])*(x-VE[i])/(VE[i+1]-VE[i])+VP[i] end do:
Digits := oldDigits:
forget(evalf);

g := unapply(piecewise(seq(p[i], i = 1 .. 15)), x):

for i to 15 do
  forget(evalf);
  print(proc(j) local res;
                res:=fsolve(g(x) = VP[j]);
                if res::numeric then res else j end if;
        end proc(i));
end do;
forget(evalf);

                                 5.444193931
                                0.4793595141
                                0.3166653569
                                0.2522053489
                                0.2123038784
                                0.1822258228
                                0.1544240625
                                0.1277082078
                                0.1055351619
                                0.08639065510
                                0.06936612570
                                0.05388339810
                                0.03955702170
                                0.02612014630
                                0.01338216460

 


Download fsolveex.mw

I learned a lot by reading closely the solutions and answers given by experts, to questions posted in public forums. For me that included reading everything that Robert Israel and Joe Riel posted on the USENET newsgroup sci.math.symbolic in the early 1990s (and later, in comp.soft-sys.math.maple).

There are also lots of great answers archived on this Mapleprimes forum. You could do a lot worse that start with the Answers posted here by Joe and Robert. Of course there are several other members here who frequently post great answers.

Another thing that I believe has helped some people gain in their advanced understanding of Maple is reading the source code of stock Library routines. Some packages, such as Statistics and Finance, are dense thickets of OO methods. And some other packages have a completely differenct style. Some routines are old, and some are new. Even without comments I find them fascinating to read. Commands that can help in looking at them include showstat, kernelopts(opaquemodules=false), interface(verboseproc=3), and print.

acer

In Maple 2015.1 this works (for me) as you expected,

indets(expr, HODD &under (convert, compose, `D`, `global`));

Maybe the next step is poking inside it, while using something like,

indets(expr, HODD &under (proc(q) local orig, res; orig:=convert(q,D); res:=convert(orig,`global`); end proc));

The conversion to `global` might be a red herring. But what is the difference between `orig` and `res` inside that custom procedure? Inside that custom proc both orig and res appear to be of type HODD. Time for hackware... but no time right now for me...

I understand that you know several other ways to get the desired answer. I interpret your question as being about what is going wrong, specifically, when it's done under AddType. On that note I'd first change the dummy name `D` in this to something else, even though it's very likely of no consequence. (One has to start somewhere, before digging into AddType...)

satisfies(D-> nops([op(D)]) > 1)

acer

The Programming Manual included in Maple 2015, in PDF format.

The Programming Manual included in Maple 18, in PDF format.

See the Documentation Center for such material.

acer

This problem is #8 on Robert Israel's list of Top Ten Maple Errors.

acer

Look in the Startup Code of a MathApp, to see the definitions of the procedures, modules, etc, accessed by its embedded components.

If you right-click on an embedded component you'll see a popup menu with an item like "Edit Value Changed Action". Selecting that menu items raises a popup editing window with the "action code" of the component. This is the code that gets executed when you move a Slider, press a Button, etc.

Most of the MathApps have very brief "action code", mostly function calls to procedures or modules that are defined elsewhere, in the Startup Code region of the App worksheet.

MathApps are worksheets that are stored in the Help database, rather than in the Library archives. That's not relevant to finding the action code. I just wanted to clarify the wording.

acer


restart:

with(RootFinding:-Parametric):

 

  Consider 1/a * (a*x^2 + b*x + c) with B=b/a, C=c/a

 

  (You can also think of this like the special case  a = 1for your original three parameter form.  It makes it easier to visualize, perhaps, with just two parameters.)

f := x^2 + B*x + C;

B*x+x^2+C

DiscriminantVariety([f=0], [x]);

[[B^2-4*C]]

m := CellDecomposition([f=0], [x]):

NumberOfSolutions(m);

[[1, 2], [2, 2], [3, 0], [4, 2]]

 

The last result above means that each point in Cell 1 has 2 roots, each point in Cell 3 has zero roots, etc.

 

CellPlot(m, 'samplepoints');

 

In other words, if  B^2-4*C > 0 then we are inside Cell 1 or 2 or 4 and there are two real roots. I leave to you the easy task of showing that there is just one real root (of multiplicity 2) when  B^2 = 4*C .  And inside Cell 3 there are no roots.

 

So if  C < (1/4)*B^2 then there are two real roots, and if  C = (1/4)*B^2then there is is only one distinct root, and if  C > (1/4)*B^2then there are no real roots.

 

Now let's revisit the form with there parameters a, b, and c.

 

F := a*x^2 + b*x + c;

a*x^2+b*x+c

discrim(F, x);

-4*a*c+b^2

plots:-implicitplot3d( discrim(F, x), a=-1..1, b=-1..1, c=-1..1,
                       grid=[35,35,35], style=patchnogrid, color=blue,
                       orientation=[55,80,-25] );

 

Take any positive value for `a`. In that case there are two real roots of F when  c < b^2/(4*a), one real root when  c = b^2/(4*a), and zero real roots when  c > b^2/(4*a).  And for negative `a` those inequalities are flipped.

 

We can get similar results from the `solve` command.

 

solve( {a*x^2 + b*x + c}, x, real, parametric );

piecewise(And(a = 0, b = 0, c = 0), [[x = x]], And(a = 0, 0 < b), [[x = -c/b]], And(a = 0, b < 0), [[x = -c/b]], And(0 < a, c = b^2/(4*a)), [[x = -(1/2)*b/a]], And(0 < a, c < b^2/(4*a)), [[x = (1/2)*(-b+sqrt(-4*a*c+b^2))/a], [x = -(1/2)*(b+sqrt(-4*a*c+b^2))/a]], And(a < 0, c = b^2/(4*a)), [[x = -(1/2)*b/a]], And(a < 0, b^2/(4*a) < c), [[x = (1/2)*(-b+sqrt(-4*a*c+b^2))/a], [x = -(1/2)*(b+sqrt(-4*a*c+b^2))/a]], [])

 


Download discrim.mw

acer

There are some situations where one does not want any expansion (or simplification) to occur other than the simplest arithmetic changes necessary to find a polynomial pattern by algsubs.

In some such cases it can help to frontend the expand call.

In the following example, I'd prefer that the 1-cos(y+v)^2 is left alone, say.


z := -d*(1-cos(y+v)^2+a)+a;

-d*(1-cos(y+v)^2+a)+a

algsubs((a-a*d)=c,expand(z));

(cos(y)^2*cos(v)^2-2*cos(y)*cos(v)*sin(y)*sin(v)+sin(y)^2*sin(v)^2-1)*d+c

simplify(z,{a-a*d=c});

(cos(y)^2*cos(v)^2-2*cos(y)*cos(v)*sin(y)*sin(v)+sin(y)^2*sin(v)^2-1)*d+c

algsubs((a-a*d)=c,frontend(expand,[z]));

(cos(y+v)^2-1)*d+c


Download frontend.mw

acer

int((a/2)*exp(-a*abs(x)),x=-infinity..infinity) assuming Re(a)>0;

                               1

Or, if a is to be real, then under the assumption that a>0.

acer

If you don't want to use the right-click context-menus then... just type out your command instead.

Also, it looks to me as if you wanted to map the commands over the whole Matrix and not over just the [1,1] entry. Yes?

 

M := Matrix([[1/7*(5*exp(-3*t)+2*exp(4*t))*exp(-t),
              2/7*(exp(-3*t)-exp(4*t))*exp(-t)],
             [5/7*(exp(-3*t)-exp(4*t))*exp(-t),
              1/7*(2*exp(-3*t)+5*exp(4*t))*exp(-t)]]);

M := Matrix(2, 2, {(1, 1) = ((5/7)*exp(-3*t)+(2/7)*exp(4*t))*exp(-t), (1, 2) = ((2/7)*exp(-3*t)-(2/7)*exp(4*t))*exp(-t), (2, 1) = ((5/7)*exp(-3*t)-(5/7)*exp(4*t))*exp(-t), (2, 2) = ((2/7)*exp(-3*t)+(5/7)*exp(4*t))*exp(-t)})

map(combine@expand,M);

Matrix(2, 2, {(1, 1) = (5/7)*exp(-4*t)+(2/7)*exp(3*t), (1, 2) = (2/7)*exp(-4*t)-(2/7)*exp(3*t), (2, 1) = (5/7)*exp(-4*t)-(5/7)*exp(3*t), (2, 2) = (2/7)*exp(-4*t)+(5/7)*exp(3*t)})

 

 

Download matrixmap.mw

acer

Yes, you can inline 2D Math into text sentences in a Document.

Use Ctl-t to toggle into text mode. In that mode you can type sentences. In mid-sentence you can use Ctl-r to toggle into 2D Input mode. And then you can toggle back to text. 

Such inlined 2D Math will not evaluate, unless you cause it to be evaluated. That is, by default it is inert 2D Math. The way to evaluate it inline is to select it (or have the cursor inside it) and then to use the keystrokes Ctl-=.

Ctl-t means the Control key and the lowercase `t` key pressed simultaneously. Similalry, Ctl-= means the Control key and the `=` key. That's on MS_Windows. On OS X (Mac) it is Command-= instead of Control-=. See here.

Here's a Document that I just made in Maple 2015 on Windows.

 

f := sin(x)

sin(x)

This is a Document. I used Ctl-t to get to text mode. Now I'll use Ctl-r to get to 2D Input mode, and I'll use Ctl-= to evaluate it inline. I'll do both those steps twice in the next sentence. The derivative of the original function f = sin(x) is diff(f, x) = cos(x). I did not type out sin(x)or cos(x)in the last sentence. Instead I used Ctl-= after using Ctl-r to enter 2D Input mode.

 

Download textandinlinedmath.mw

Note that once such inlined math is evaluated inline (within some text) it cannot be turned back into inert 2D Math. In can be deleted, though. If you change the code which assigns to `f` say, and then reevaluate the whole worksheet then the previously evaluated inline math involving `f` gets reevealuated and shows the new assigned value.

You can change the style used for displayed 2D Math output so that it appears black instead of blue. That's just part of the usual customizing of styles (character, paragraph, etc) that can be done within a Document,

acer

I'm not sure how you (or Maple TA) is generating the random aspects of the assignments. But you might try forcing the random seed which is used by several of Maple's internal random number generators. (Ie, the TA process might fortuitously happen to rely on this. You could at least try it..)

See the randomize comand. The idea is that you could try forcing its r parameter (the random seed) according to each student, at the start of the code which generates the assignments.

acer

On way to get that effect is via piecewise structures.

 

f:=x^3-5*x^2+x+5:

plot([piecewise(f>0,f,undefined),piecewise(f<0,f,undefined)],

     x=-2..5, color=[blue,red]);

 

 

Download 2Dplotcolor.mw

plot3d supports a colorfunc option to use a procedure for coloring. The plot command should be given that as well.

acer

You might prefer the result if you used inert Sum instead of active sum. The latter is producing the GAMMA calls which you had trouble getting rid of.


MTBF = solve(R = exp(t/MTBF) * (t/MTBF) * Sum(1/(i!), i=0..n),MTBF);

MTBF = t/LambertW(R/(Sum(1/factorial(i), i = 0 .. n)))

restart:

eqn1:= R = exp(t/MTBF) * (t/MTBF) * sum(1/(i!), i=0..n);

R = exp(t/MTBF)*t*exp(1)*GAMMA(n+1, 1)/(MTBF*GAMMA(n+1))

eqn2:= MTBF = solve(eqn1,MTBF):

simplify(convert(eqn2,compose,Sum,factorial)) assuming n::posint;

MTBF = t/LambertW((Sum((-1)^_k1/factorial(_k1), _k1 = 0 .. infinity))*R*exp(1)/(Sum(1/factorial(_k1), _k1 = 0 .. n)))

 


Download LW.mw

acer

You could try something like this, with alias.


restart:

aliasedlatex:=proc(e)
  local lookup;
  lookup:=op(eval(alias:-ContentToGlobal)):
  :-latex(eval(e,lookup));
  NULL;
end proc:

alias(Y=X(a,b,c)):

test:=X(a,b,c):

latex(test);

X \left( a,b,c \right)

aliasedlatex(test);

Y

H:=sin(test)+1/test:

latex(H);

\sin \left( X \left( a,b,c \right)  \right) + \left( X \left( a,b,c

 \right)  \right) ^{-1}

aliasedlatex(H);

\sin \left( Y \right) +{Y}^{-1}

 


Download aliasedlatex.mw

acer

First 222 223 224 225 226 227 228 Last Page 224 of 336