mmcdara

7891 Reputation

22 Badges

9 years, 63 days

MaplePrimes Activity


These are replies submitted by mmcdara

@Robert Matlock 

Could it be that you want to make sure that the numerical scheme used by dsolve is accurate enough for your purpose?
That is that you would want to insure the truncation error is small enoudh or that the modified equation (the continuous one the numerical scheme really solves) is close enough to the continuous equation you want to solve?

If it is so, there exist mathematical techniques to obtain either the truncation error or the modified equation.
Truncation error is the most classic and all math textbooks about numerical solving of ODEs contain (for toy problems, mainly linear) its expression for a lot of schemes (most of them avaliable in dsolve).

For more complicated case (ie. nonlinear odes) one often use the Method of Manufactured Solution (MMS).
The attached file gives an example.
Applying this method to the differential operator of your own problem, whilecarefully chosing several manufactured solutions, should help you to discriminate amid the "good" and "bad" numerical schemes and set the tolerances or grid size values.
 

restart:

ode := diff(u(x), x$2)*(1+diff(u(x),x)^2) + u(x)*diff(u(x),x) = 1/(1+15*x^2);
bv  := u(0)=1, u(1)=1/2;

sol := dsolve({ode, bv }, numeric);

plots:-odeplot(sol, [x, u(x)], x=0..1);

# Is this a reliable approximation of the true solution?

(diff(diff(u(x), x), x))*(1+(diff(u(x), x))^2)+u(x)*(diff(u(x), x)) = 1/(15*x^2+1)

 

u(0) = 1, u(1) = 1/2

 

proc (x_bvp) local res, data, solnproc, _ndsol, outpoint, i; option `Copyright (c) 2000 by Waterloo Maple Inc. All rights reserved.`; _EnvDSNumericSaveDigits := Digits; Digits := 15; if _EnvInFsolve = true then outpoint := evalf[_EnvDSNumericSaveDigits](x_bvp) else outpoint := evalf(x_bvp) end if; data := Array(1..4, {(1) = proc (outpoint) local X, Y, YP, yout, errproc, L, V, i; option `Copyright (c) 2000 by Waterloo Maple Inc. All rights reserved.`; X := Vector(8, {(1) = .0, (2) = .12826886497223997, (3) = .26113777569397906, (4) = .40154761998091554, (5) = .5494211741595527, (6) = .7027818747480806, (7) = .8595681924875884, (8) = 1.0}, datatype = float[8], order = C_order); Y := Matrix(8, 2, {(1, 1) = 1.0, (1, 2) = -.8414172775411444, (2, 1) = .9007826428616932, (2, 2) = -.7082299965860446, (3, 1) = .8144476066224402, (3, 2) = -.5966120260026161, (4, 1) = .7371072611596353, (4, 2) = -.5095254313980015, (5, 1) = .6670249224566486, (5, 2) = -.4415965878326471, (6, 1) = .6035883533804827, (6, 2) = -.3880057661417157, (7, 1) = .546239605544721, (7, 2) = -.3452272743149798, (8, 1) = .5, (8, 2) = -.3143013506393865}, datatype = float[8], order = C_order); YP := Matrix(8, 2, {(1, 1) = -.8414172775411444, (1, 2) = 1.07812386883615, (2, 1) = -.7082299965860446, (2, 2) = .9589961107852607, (3, 1) = -.5966120260026161, (3, 2) = .7229274327553343, (4, 1) = -.5095254313980015, (4, 2) = .5303930579097911, (5, 1) = -.4415965878326471, (5, 2) = .3978675061925884, (6, 1) = -.3880057661417157, (6, 2) = .3069166956844302, (7, 1) = -.3452272743149798, (7, 2) = .2424437573985556, (8, 1) = -.3143013506393865, (8, 2) = .1999031726404807}, datatype = float[8], order = C_order); errproc := proc (x_bvp) local outpoint, X, Y, yout, L, V, i; option `Copyright (c) 2000 by Waterloo Maple Inc. All rights reserved.`; Digits := 15; outpoint := evalf(x_bvp); X := Vector(8, {(1) = .0, (2) = .12826886497223997, (3) = .26113777569397906, (4) = .40154761998091554, (5) = .5494211741595527, (6) = .7027818747480806, (7) = .8595681924875884, (8) = 1.0}, datatype = float[8], order = C_order); Y := Matrix(8, 2, {(1, 1) = .0, (1, 2) = 0.10890358515582652e-6, (2, 1) = -0.1273188731185599e-6, (2, 2) = 0.1433045594562052e-6, (3, 1) = -0.8927520188200564e-7, (3, 2) = 0.58257129736926296e-7, (4, 1) = -0.58336959823718046e-7, (4, 2) = 0.10428023193887122e-6, (5, 1) = -0.41584070894710373e-7, (5, 2) = 0.10452293110652422e-6, (6, 1) = -0.26811723670178546e-7, (6, 2) = 0.9748340266920589e-7, (7, 1) = -0.12413653369215185e-7, (7, 2) = 0.9099748924152847e-7, (8, 1) = .0, (8, 2) = 0.8633932517444991e-7}, datatype = float[8], order = C_order); if not type(outpoint, 'numeric') then if outpoint = "start" or outpoint = "left" then return X[1] elif outpoint = "right" then return X[8] elif outpoint = "order" then return 6 elif outpoint = "error" then return HFloat(1.433045594562052e-7) elif outpoint = "errorproc" then error "this is already the error procedure" elif outpoint = "rawdata" then return [2, 8, [u(x), diff(u(x), x)], X, Y] else return ('procname')(x_bvp) end if end if; if outpoint < X[1] or X[8] < outpoint then error "solution is only defined in the range %1..%2", X[1], X[8] end if; V := array([1 = 4, 2 = 0]); if Digits <= trunc(evalhf(Digits)) then L := Vector(4, 'datatype' = 'float'[8]); yout := Vector(2, 'datatype' = 'float'[8]); evalhf(`dsolve/numeric/lagrange`(8, 2, X, Y, outpoint, var(yout), var(L), var(V))) else L := Vector(4, 'datatype' = 'sfloat'); yout := Vector(2, 'datatype' = 'sfloat'); `dsolve/numeric/lagrange`(8, 2, X, Y, outpoint, yout, L, V) end if; [x = outpoint, seq('[u(x), diff(u(x), x)]'[i] = yout[i], i = 1 .. 2)] end proc; if not type(outpoint, 'numeric') then if outpoint = "start" or outpoint = "left" then return X[1] elif outpoint = "method" then return "bvp" elif outpoint = "right" then return X[8] elif outpoint = "order" then return 6 elif outpoint = "error" then return HFloat(1.433045594562052e-7) elif outpoint = "errorproc" then return eval(errproc) elif outpoint = "rawdata" then return [2, 8, "depnames", X, Y, YP] else error "non-numeric value" end if end if; if outpoint < X[1] or X[8] < outpoint then error "solution is only defined in the range %1..%2", X[1], X[8] end if; if Digits <= trunc(evalhf(Digits)) and (_EnvInFsolve <> true or _EnvDSNumericSaveDigits <= trunc(evalhf(Digits))) then V := array( 1 .. 6, [( 1 ) = (7), ( 2 ) = (0), ( 3 ) = (false), ( 4 ) = (false), ( 5 ) = (false), ( 6 ) = (false)  ] ); L := Matrix(7, 2, {(1, 1) = .0, (1, 2) = .0, (2, 1) = .0, (2, 2) = .0, (3, 1) = .0, (3, 2) = .0, (4, 1) = .0, (4, 2) = .0, (5, 1) = .0, (5, 2) = .0, (6, 1) = .0, (6, 2) = .0, (7, 1) = .0, (7, 2) = .0}, datatype = float[8], order = C_order); yout := Vector(2, {(1) = .0, (2) = .0}, datatype = float[8]); evalhf(`dsolve/numeric/hermite`(8, 2, X, Y, YP, outpoint, var(yout), var(L), var(V))) else if _EnvInFsolve = true then Digits := _EnvDSNumericSaveDigits end if; V := array( 1 .. 6, [( 1 ) = (7), ( 2 ) = (0), ( 3 ) = (false), ( 4 ) = (false), ( 5 ) = (false), ( 6 ) = (false)  ] ); L := Matrix(7, 2, {(1, 1) = 0., (1, 2) = 0., (2, 1) = 0., (2, 2) = 0., (3, 1) = 0., (3, 2) = 0., (4, 1) = 0., (4, 2) = 0., (5, 1) = 0., (5, 2) = 0., (6, 1) = 0., (6, 2) = 0., (7, 1) = 0., (7, 2) = 0.}, order = C_order); yout := Vector(2, {(1) = 0., (2) = 0.}); `dsolve/numeric/hermite`(8, 2, X, Y, YP, outpoint, yout, L, V) end if; [outpoint, seq(yout[i], i = 1 .. 2)] end proc, (2) = Array(0..0, {}), (3) = [x, u(x), diff(u(x), x)], (4) = 0}); solnproc := data[1]; if not type(outpoint, 'numeric') then if outpoint = "solnprocedure" then return eval(solnproc) elif member(outpoint, ["start", "left", "right", "errorproc", "rawdata", "order", "error"]) then return solnproc(x_bvp) elif outpoint = "sysvars" then return data[3] elif procname <> unknown then return ('procname')(x_bvp) else _ndsol := pointto(data[2][0]); return ('_ndsol')(x_bvp) end if end if; try res := solnproc(outpoint); [x = res[1], seq('[u(x), diff(u(x), x)]'[i] = res[i+1], i = 1 .. 2)] catch: error  end try end proc

 

 

# MMS : Let's choose a function which verifies the bv

U__MMS := x -> 1-x/2

proc (x) options operator, arrow; 1-(1/2)*x end proc

(1)

# Obviously ode is not verified if one replace u by U__MMS.
# But if we replace its rhs by rhs__MMS computed this way

rhs__MMS := eval(lhs(ode), u(x)=U__MMS(x));

-1/2+(1/4)*x

(2)

# then the solution of

 ode__MMS := diff(u(x), x$2)*(1+diff(u(x),x)^2) + u(x)*diff(u(x),x) = rhs__MMS

(diff(diff(u(x), x), x))*(1+(diff(u(x), x))^2)+u(x)*(diff(u(x), x)) = -1/2+(1/4)*x

(3)

# should be U__MMS.
# Let's verify this

sol__MMS := dsolve({ode__MMS, bv }, numeric);

plots:-display(
  plots:-odeplot(sol__MMS, [x, u(x)], x=0..1, color=red),
  plot(U__MMS(x), x=0..1, style=point, symbol=circle, numpoints=20, color=blue),
  gridlines=true
);

proc (x_bvp) local res, data, solnproc, _ndsol, outpoint, i; option `Copyright (c) 2000 by Waterloo Maple Inc. All rights reserved.`; _EnvDSNumericSaveDigits := Digits; Digits := 15; if _EnvInFsolve = true then outpoint := evalf[_EnvDSNumericSaveDigits](x_bvp) else outpoint := evalf(x_bvp) end if; data := Array(1..4, {(1) = proc (outpoint) local X, Y, YP, yout, errproc, L, V, i; option `Copyright (c) 2000 by Waterloo Maple Inc. All rights reserved.`; X := Vector(8, {(1) = .0, (2) = .14285714285714282, (3) = .28571428571428564, (4) = .4285714285714285, (5) = .5714285714285715, (6) = .7142857142857144, (7) = .8571428571428572, (8) = 1.0}, datatype = float[8], order = C_order); Y := Matrix(8, 2, {(1, 1) = 1.0, (1, 2) = -.5, (2, 1) = .9285714285714286, (2, 2) = -.5, (3, 1) = .8571428571428572, (3, 2) = -.5, (4, 1) = .7857142857142857, (4, 2) = -.5, (5, 1) = .7142857142857142, (5, 2) = -.5, (6, 1) = .6428571428571428, (6, 2) = -.5, (7, 1) = .5714285714285714, (7, 2) = -.5, (8, 1) = .5, (8, 2) = -.5}, datatype = float[8], order = C_order); YP := Matrix(8, 2, {(1, 1) = -.5, (1, 2) = .0, (2, 1) = -.5, (2, 2) = 0.5551115123125783e-17, (3, 1) = -.5, (3, 2) = 0.11102230246251566e-16, (4, 1) = -.5, (4, 2) = -0.22204460492503132e-16, (5, 1) = -.5, (5, 2) = -0.22204460492503132e-16, (6, 1) = -.5, (6, 2) = .0, (7, 1) = -.5, (7, 2) = .0, (8, 1) = -.5, (8, 2) = .0}, datatype = float[8], order = C_order); errproc := proc (x_bvp) local outpoint, X, Y, yout, L, V, i; option `Copyright (c) 2000 by Waterloo Maple Inc. All rights reserved.`; Digits := 15; outpoint := evalf(x_bvp); X := Vector(8, {(1) = .0, (2) = .14285714285714282, (3) = .28571428571428564, (4) = .4285714285714285, (5) = .5714285714285715, (6) = .7142857142857144, (7) = .8571428571428572, (8) = 1.0}, datatype = float[8], order = C_order); Y := Matrix(8, 2, {(1, 1) = .0, (1, 2) = .0, (2, 1) = .0, (2, 2) = .0, (3, 1) = .0, (3, 2) = .0, (4, 1) = .0, (4, 2) = .0, (5, 1) = .0, (5, 2) = .0, (6, 1) = .0, (6, 2) = .0, (7, 1) = .0, (7, 2) = .0, (8, 1) = .0, (8, 2) = .0}, datatype = float[8], order = C_order); if not type(outpoint, 'numeric') then if outpoint = "start" or outpoint = "left" then return X[1] elif outpoint = "right" then return X[8] elif outpoint = "order" then return 2 elif outpoint = "error" then return HFloat(-0.0) elif outpoint = "errorproc" then error "this is already the error procedure" elif outpoint = "rawdata" then return [2, 8, [u(x), diff(u(x), x)], X, Y] else return ('procname')(x_bvp) end if end if; if outpoint < X[1] or X[8] < outpoint then error "solution is only defined in the range %1..%2", X[1], X[8] end if; V := array([1 = 4, 2 = 0]); if Digits <= trunc(evalhf(Digits)) then L := Vector(4, 'datatype' = 'float'[8]); yout := Vector(2, 'datatype' = 'float'[8]); evalhf(`dsolve/numeric/lagrange`(8, 2, X, Y, outpoint, var(yout), var(L), var(V))) else L := Vector(4, 'datatype' = 'sfloat'); yout := Vector(2, 'datatype' = 'sfloat'); `dsolve/numeric/lagrange`(8, 2, X, Y, outpoint, yout, L, V) end if; [x = outpoint, seq('[u(x), diff(u(x), x)]'[i] = yout[i], i = 1 .. 2)] end proc; if not type(outpoint, 'numeric') then if outpoint = "start" or outpoint = "left" then return X[1] elif outpoint = "method" then return "bvp" elif outpoint = "right" then return X[8] elif outpoint = "order" then return 2 elif outpoint = "error" then return HFloat(-0.0) elif outpoint = "errorproc" then return eval(errproc) elif outpoint = "rawdata" then return [2, 8, "depnames", X, Y, YP] else error "non-numeric value" end if end if; if outpoint < X[1] or X[8] < outpoint then error "solution is only defined in the range %1..%2", X[1], X[8] end if; if Digits <= trunc(evalhf(Digits)) and (_EnvInFsolve <> true or _EnvDSNumericSaveDigits <= trunc(evalhf(Digits))) then V := array( 1 .. 6, [( 1 ) = (7), ( 2 ) = (0), ( 3 ) = (false), ( 4 ) = (false), ( 5 ) = (false), ( 6 ) = (false)  ] ); L := Matrix(7, 2, {(1, 1) = .0, (1, 2) = .0, (2, 1) = .0, (2, 2) = .0, (3, 1) = .0, (3, 2) = .0, (4, 1) = .0, (4, 2) = .0, (5, 1) = .0, (5, 2) = .0, (6, 1) = .0, (6, 2) = .0, (7, 1) = .0, (7, 2) = .0}, datatype = float[8], order = C_order); yout := Vector(2, {(1) = .0, (2) = .0}, datatype = float[8]); evalhf(`dsolve/numeric/hermite`(8, 2, X, Y, YP, outpoint, var(yout), var(L), var(V))) else if _EnvInFsolve = true then Digits := _EnvDSNumericSaveDigits end if; V := array( 1 .. 6, [( 1 ) = (7), ( 2 ) = (0), ( 3 ) = (false), ( 4 ) = (false), ( 5 ) = (false), ( 6 ) = (false)  ] ); L := Matrix(7, 2, {(1, 1) = 0., (1, 2) = 0., (2, 1) = 0., (2, 2) = 0., (3, 1) = 0., (3, 2) = 0., (4, 1) = 0., (4, 2) = 0., (5, 1) = 0., (5, 2) = 0., (6, 1) = 0., (6, 2) = 0., (7, 1) = 0., (7, 2) = 0.}, order = C_order); yout := Vector(2, {(1) = 0., (2) = 0.}); `dsolve/numeric/hermite`(8, 2, X, Y, YP, outpoint, yout, L, V) end if; [outpoint, seq(yout[i], i = 1 .. 2)] end proc, (2) = Array(0..0, {}), (3) = [x, u(x), diff(u(x), x)], (4) = 0}); solnproc := data[1]; if not type(outpoint, 'numeric') then if outpoint = "solnprocedure" then return eval(solnproc) elif member(outpoint, ["start", "left", "right", "errorproc", "rawdata", "order", "error"]) then return solnproc(x_bvp) elif outpoint = "sysvars" then return data[3] elif procname <> unknown then return ('procname')(x_bvp) else _ndsol := pointto(data[2][0]); return ('_ndsol')(x_bvp) end if end if; try res := solnproc(outpoint); [x = res[1], seq('[u(x), diff(u(x), x)]'[i] = res[i+1], i = 1 .. 2)] catch: error  end try end proc

 

 

# error

plots:-odeplot(
  sol__MMS, [x, u(x)-U__MMS(x)], x=0..1,
  color=red, gridlines=true,
  labels=["x", "error"], labeldirections=[default, "vertical"]
)

 

 


 

Download MMS.mw

 

 

@acer 

Sure, this seems like a good idea for... Maple 2021 maybe?

See you soon

@acer 

Blimey!
You had already told me that for matrixplot a few weeks ago!
Sorry for the inconvenience.

@tomleslie 

You're right.
If I do remember correctly the 2015 Maple version (and even maybe another one, was it 2016 ?)  suffered some problems when running on MacOS X.
I had delayed my purchase of Maple 2015 during several months for this reason and since then I've been very careful to renewing my 2015 (some have even talked recently about compatibility issues between Maple 2019 and MacOS Catalina... )

@Axel Vogt 

Thanks Axel, 

it also appears to work this way

numelems([solve( simplify(LegendreP(18,x), 'LegendreP') )])
                               18

 

Thanks, 

Here is my file with interface(version) included
 

restart:

interface(version)

`Standard Worksheet Interface, Maple 2015.2, Mac OS X, December 21 2015 Build ID 1097895`

(1)

Z := n -> op~(2, { allvalues(solve(LegendreP(n,x))) } );

proc (n) options operator, arrow; `~`[op](2, {allvalues(solve(LegendreP(n, x)))}) end proc

(2)

Digits:=10:
Z(17):
numelems(%);

17

(3)

Z(18):
numelems(%);

16

(4)

Digits:=15:
Z(18):
numelems(%);

16

(5)

Digits:=20:
Z(18):
numelems(%);

15

(6)

 


 

Download LegendreP_zeros.mw

@nm 

Thanks nm, maybe an old bug?

Even forcing maxsols=n doesn't help.

@acer 

Thanks for having corrected the product field.

@vv 

Why did I pick up at noon to 2:00 p.m.?

Thanks, I vote up;

ps: the output of  (2*A * B^(-1) - C)^* is not very pretty (1/B instead of B-1)

 

@Carl Love @nm @acer @tomleslie

Thanks to all of you.
Decidedly I have to replace my personal license.

 

@Carl Love 

Thanks for your reply (I wasn't aware of the appliable type checking).

PS: I guess you have a little typo in the last line of the second code snippet; probably

div5(f(5));

instead of

div5(f[5]);

@Carl Love 

Hi, 
what do you think about a syntax like 

f := i -> x -> sin(i*x);

to define a two-stage" function?
It seems to me this is a better syntax than f[i](x), for instance,  for which i looks more like an index than a parameter.

 

Another way based on MathML coding:
 

ks := [123, 456, 789, 101112];
Ns := [seq](1900..1960, 20);

code := (k, N) -> parse(cat("`#mrow(mfrac(mo(", k, "),mo(", N, ")))`")):

plot(sqrt(x) - 0.5,  x= 0..10, axis[1]=[tickmarks=[seq(2*k=code(ks[k], Ns[k]), k=1..4)]])

Download With_MathML.mw

@vv @tomleslie

Until now I used to save the solution procedure in a ".m" file for later use the solution procedure and to save in the same file the bold quantity below  (if any)

sol := solve(sys, numeric, parameters=params)

This until I realized that sol(parameters) enabled recovering the list of the parameters.
Thus I thought that saving params was useless and decided to save sol alone.

What you both say, if I understand correctly, is that I have to save params also (it's not for the size it costs...)?

 

i don't know what you want to do, but if you just want do obtain the output LaTeX code fir your Matrix do 

latex(B);

and copy-paste the result in your LaTeX document within the \begin{S} ... \end{S} structure S you want.
Anyway, no automatic Maple code generation of the LaTeX code will be able to correctly handle all cases (matrix on two pages, centering, scaling in case there are a lot of columns...).
In all cases you will have to finish the work by hand (unless you use LaTex as Word and don't care about the beauty of the document).
 

First 95 96 97 98 99 100 101 Last Page 97 of 154