I want to plot two graphs: numeric solution of DE and Taylor series approximation for DE given. I have
de := diff(y(x), x$2) = x+y(x)-y(x)^2;
cond := y(0) = -1, (D(y))(0) = 1;
stp := 0.1e-1;
a, b := -5, 30;
numpts := floor((b-a)/stp+1);
p := dsolve({cond, de}, y(x), numeric, stepsize = stp, output = listprocedure);
Plotting eval gives weird vertical line, while I expect to obtain plot that seems to oscillate as x -> ∞. For Taylor series, I've tried f:=[seq(taylor(y(x),x=i,n),i=-5..30 by stp)]; but seems like it won't work in such a way. What can I do with it? Why does my plot differ from expected?
restart;
kernelopts(version);
Maple 2018.0, X86 64 LINUX, Mar 9 2018, Build ID 1298750
de := diff(y(x), x$2) = x+y(x)-y(x)^2:
cond := y(0) = -1, (D(y))(0) = 1:
stp := 0.1e-1:
a, b := -5, 30:
numpts := floor((b-a)/stp+1):
p := dsolve({cond, de}, y(x), numeric, stepsize = stp,
output = listprocedure):
Y:=eval(y(x),p);
Y := proc(x) ... end;
plot(Y, 0..20);
Order:=10:
S := convert(rhs(dsolve({cond, de}, {y(x)}, series)),polynom);
plot([S, Y(x)], x=0..1.5);
Order:=40:
S := convert(rhs(dsolve({cond, de}, {y(x)}, series)),polynom):
plot([S, Y(x)], x=0..2.0);
Related
I'M TRYIN TO CREATE A PROGRAM USING MAPLE FOR GAUSSING ELIMINATION BUT I KEEP GETTING THIS ERROR
Gauss := proc (n::posint, A::matrix, c::Vector)
local a, i, k, j, p;
with(MTM):
n := linalg[rowdim](A);
if det(A) = 0 then print('matrice*doit*etre*caree')
else if det(A) <> 0
then a := `<|>`(A, c);
for k to n-1 do
for i from k+1 to n do
if a[i, i] = 0 then swaprow(a, k, i)
else p = a[i, k]/a[k, k];
for j from k+1 to n+1 do a[i, j] = a[i, j]-p*a[k, j]
end do;
end if;
end do;
end do;
else print('rien')
end if; end if; end proc;
Error, (in Gauss) illegal use of a formal parameter
restart;
Gauss := proc(A::Matrix, c::Vector)
local a, i, k, j, m, n, p;
n := linalg[rowdim](A);
m := linalg[coldim](A);
if m <> n then
print("matrice doit etre caree");
else
a := `<|>`(A, c);
for k to n-1 do
for i from k+1 to n do
if a[i, i] = 0 then
a := linalg[swaprow](a, k, i);
else
p := a[i, k]/a[k, k];
for j from k to n+1 do
a[i, j] := a[i, j]-p*a[k, j];
end do;
end if;
end do;
end do;
end if;
return a;
end proc:
c := Vector([2, 3, 4]);
A := Matrix(3, 3, [4, 1, 2, 3, 6, 5, 2, 1, 9]);
Gauss(A, c);
LinearAlgebra:-LUDecomposition(<A|c>, output=U);
There were quite a few mistakes, so let's hope I get most of them.
I didn't bother doing 7. You should do it.
You cannot use with inside a procedure.
Your code uses commands from thelinalg
package, not the MTM package.
Ideally you'd use Matrix&Vector&LinearAlgebra
(instead of your mix of matrix&Vector&linalg(.
Your procedure has n as one of its
parameters, but inside it you also try to
assign a value to n, the argument for which
you passed in as the number 3. That's where
your error message is coming from. You can't
do that.
Several of you lines have just = instead of
:= for assignments. The = does nothing.
The test against det(A)=0 is wrong is wrong
in several ways. I'll just say that it doesn't
actually test whether the A is square.
Compare the row & column dimensions if you
want to test that A is square.
You should be using LinearAlgebra
equivalents instead of the linalg commands
commands swaprow, coldim.
You forgot to have your procedure actually
return the Matrix a.
When your code calls swaprow is was not
actually updating a. It was just throwing
way the result.
It's a sin to not indent your code. It will
lead you to overlook mistakes.
How is it going guys ?
I've written a program that "draws" diamond in the command line (it's a part of my homework). For spaces inside the diamond I was given a formula "1 + 2(k-2) or 2k -3 , where k is line number", but I don't understand how this formula was created. Could anyone explain it ?
program diamond;
var
n, k, h, i: integer;
begin
repeat
write('Enter the diamond''s height (positive odd): ');
readln(h);
until (h > 0) and (h mod 2 = 1);
n := h div 2;
for k := 1 to n + 1 do
begin
for i := 1 to n + 1 - k do
write(' ');
write('*');
if k > 1 then
begin
for i := 1 to 2*k - 3 do
write(' ');
write('*')
end;
writeln
end;
for k := n downto 1 do
begin
for i := 1 to n + 1 - k do
write(' ');
write('*');
if k > 1 then
begin
for i := 1 to 2*k - 3 do
write(' ');
write('*')
end;
writeln
end
end.
I've already figured it out. It's a simple, but modified arithmetic progression An=A1-d(n-2). Usually we would use (n-1), but because we need to substract 2 stars from each line (starting from the second one, as this formula works for k>1), we use (n-2)
I don't understand how to use a mathematical function in a maple procedure.
For example in this procedure I try to compute the arc length of a function :
proc(f,a,b);
local f,a,b;
L=int(sqrt(1+f'(x)^2),x=a..b);
end proc;
But is doesn't work.
It is my first question here if there is a problem
Firstly, the syntax f'(x) is only valid in Maple's marked up 2S Math, not in plaintext Maple code. So it does not make sense to show us that syntax as code on this site.
Moving on, and using only 1D plaintext code (which makes sense for this site and is, in my opinion, a better choice for learning Maple), you need to understand the difference between procedures and expresssions.
An expressiom and differentiating it:
Fexpr := x^2 + sin(x);
2
Fexpr := x + sin(x)
diff(Fexpr, x);
2 x + cos(x)
An operator, and differentiating it (and applying it, or applying it after differentiating):
F := t -> t^2 + sin(t);
F := t -> t^2 + sin(t)
D(F);
t -> 2*t + cos(t)
D(F)(x);
2 x + cos(x)
F(x);
2
x + sin(x)
diff(F(x), x);
2 x + cos(x)
Here are some examples:
Your task, done with argument f as an expression, and supplying the variable name as an argument:
restart;
myproc := proc(fexpr,a,b,var)
local L;
L:=int(sqrt(1+diff(fexpr,var)^2),var=a..b);
end proc:
myproc(sin(x), 0, Pi, x);
myproc(sin(x), 0.0, evalf(Pi), x);
myproc(sin(t), 0.0, evalf(Pi), t);
myproc(t^2, 0, Pi, t);
A modification of the above, where it figures out the variable name from the expression passed as argument:
restart;
myproc := proc(fexpr,a,b)
local deps,L,x;
deps := indets(fexpr,
And(name,Not(constant),
satisfies(u->depends(fexpr,u))));
x := deps[1];
L:=int(sqrt(1+diff(fexpr,x)^2),x=a..b);
end proc:
myproc(sin(x), 0, Pi);
myproc(sin(x), 0.0, evalf(Pi));
myproc(sin(t), 0.0, evalf(Pi));
myproc(t^2, 0, Pi);
Now, significantly different, passing an procedure (operator) instead of an expression:
restart;
myproc := proc(f,a,b)
local L,x;
L:=int(sqrt(1+D(f)(x)^2),x=a..b);
end proc:
myproc(sin, 0, Pi);
myproc(sin, 0.0, evalf(Pi));
myproc(s -> s^2, 0, Pi);
Lastly (and I do not recommend this way, since the procedure f may not function properly when called with an unassigned name, etc):
restart;
myproc := proc(f,a,b)
local L,x;
L:=int(sqrt(1+diff(f(x),x)^2),x=a..b);
end proc:
myproc(sin, 0, Pi);
myproc(sin, 0.0, evalf(Pi));
myproc(s -> s^2, 0, Pi);
I have a set of experimental data (P), and I want to obtain plot "experimental vs predicted". In order to do so, I use another set of data which depend on P (Q), plot ScatterPlot, use appropriate fit, then obtain regression line, and use its coefficients in appropriate differential equation. Plot of P looks good, but I need to add there experimental data. For simplicity, I've used interval t=0..150.
How can I plot experimental data so that P(0) = Pvals[1], P(10)=Pvals[2], etc.? Besides, how can I distribute data (say, I have t=0..800 and want to plot Pvals so that P(0) = Pvals[1] and P(800) = Pvals[16])?
Pvals := [3.929, 5.308, 7.24, 9.638, 12.866, 17.069, 23.192, 31.433, 38.558, 50.156, 62.948,
75.996, 91.972, 105.711, 122.775, 131.669]:
for i to 15 do Qval[i] := .1*(Pvals[i+1]/Pvals[i]-1); end do:
Qvals := [seq(Qval[i], i = 1 .. 15), 0.144513895e-1]:
with(Statistics);
ScatterPlot(Pvals, Qvals, fit = [a*v^2+b*v+c, v], thickness = 3,
legend = [points = "Point data", fit = typeset("fit to a", 2^nd, "degree polynomial")]);
with(CurveFitting);
LeastSquares(Pvals, Qvals, v, curve = a*v^2+b*v+c);
de := diff(P(t), t) = (0.370152282598477e-1-0.272504103112702e-3*P(t))*P(t);
sol := dsolve({de, P(0) = 3.929}, P(t));
P := plot(rhs(sol), t = 0 .. 160);
I'm not sure that I entirely follow your methodology. But is this something like what you are trying to accomplish?
restart;
with(Statistics):
Pvals := [3.929, 5.308, 7.24, 9.638, 12.866, 17.069, 23.192, 31.433,
38.558, 50.156, 62.948, 75.996, 91.972, 105.711, 122.775, 131.669]:
for i to 15 do Qval[i] := .1*(Pvals[i+1]/Pvals[i]-1); end do:
Qvals := [seq(Qval[i], i = 1 .. 15), 0.144513895e-1]:
form := a*v^2+b*v+c:
CF := CurveFitting:-LeastSquares(Pvals, Qvals, v, curve = form);
CF := 0.0370152282598477 - 0.000272504103112702 v
-7 2
+ 5.60958249026713 10 v
Now I use CF in the DE (since I don't understand why you dropped the v^2 term),
#de := diff(P(t), t) = (0.370152282598477e-1-0.272504103112702e-3*P(t))*P(t);
de := diff(P(t), t) = eval(CF, v=P(t))*P(t);
d /
de := --- P(t) = \0.0370152282598477 - 0.000272504103112702 P(t)
dt
-7 2\
+ 5.60958249026713 10 P(t) / P(t)
I'll use the numeric option of the dsolve command, and obtain a procedure that computes P(t) for numeric t values.
sol := dsolve({de, P(0) = 3.929}, P(t), numeric, output=listprocedure ):
Pfunc := eval(P(t), sol);
Pfunc := proc(t) ... end;
Pfunc(0.0), Pvals[1];
3.92900000000000, 3.929
Now some rescaling (which, again, is my guess as to your goal),
endpt := fsolve(Pfunc(t)-Pvals[16]);
endpt := 135.2246055
Pfunc(endpt), Pvals[16];
131.669000003321, 131.669
plot(Pfunc(t), t=0 .. endpt, size=[500,200]);
a,b,N := 0.0, 800.0, nops(Pvals);
a, b, N := 0., 800.0, 16
Pfuncscaled := proc(t)
if not t::numeric then
return 'procname'(args);
end if;
Pfunc(t*endpt/b);
end proc:
Pfuncscaled(0), Pvals[1];
3.92900000000000, 3.929
Pfuncscaled(800), Pvals[N];
131.669000003321, 131.669
PLscaled := plot( Pfuncscaled(t), t=a .. b,
color=red, size=[500,200] );
Now to display the Pdata against 0 .. 800 as well,
V := Vector(N, (i)->a+(i-1)*(b-a)/(N-1)):
V[1], V[-1];
0., 800.0000000
Pdatascaled := plot( < V | Vector(Pvals) >,
color=blue, size=[500,200],
style=pointline, symbol=solidcircle );
And, displaying the rescaled data together with the rescaled procedure from dsolve,
plots:-display( PLscaled, Pdatascaled, size=[500,500] );
I have a differential equation that my program solves:
p := dsolve({ic, sys}, numeric, method = rosenbrock);
After solving we have the following:
print(p(10));
[t = 10., alpha(t) = HFloat(0.031724302221312055), beta(t) = HFloat(0.00223975915581258)]
I need use this alpha(t) and beta(t) as follows:
a := t->exp( int(alpha(t)),x=0..t) );
b := t->exp( int(beta(t)),x=0..t) )
And draw a plot:
odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 500, color = [red, blue])
The first thing that occurred to do so:
p := dsolve({sys, ic}, numeric, method=rosenbrock);
alpha := t->rhs(p(t)[2] );
beta := t->rhs(p(t)[3;
a := t->exp( int(alphat)),x=0..t) );
b := t->exp( int(betat)),x=0..t) );
odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20, thickness = 2, numpoints = 500, color = [red, blue])
But the code does not work, and Yes, obviously, should act differently.
First, let's try to get your approach to work, with a few syntax and usage changes.
You didn't supply the example's details, so I make up a system of differential equations sys and initial conditions ic so that your computational commands can be performed.
restart:
sys := diff(alpha(t),t) = -1/200*beta(t),
diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2:
ic := alpha(0)=0, beta(0)=-1:
p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):
alphat := eval(alpha(t),p):
betat := eval(beta(t),p):
a := unapply( exp( Int(alphat , 0..t) ), t, numeric):
b := unapply( exp( Int(betat , 0..t) ), t, numeric):
evalf(a(20.0)), evalf(b(20.0));
-18
5.347592595, 3.102016550 10
st := time():
P := plots:-odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20,
thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;
16.770 seconds
P;
I used output=listprocedure so that I could assign the right procedures from solution p to alphat and betat. Those are more efficient to call many times, as opposed to your original which formed a sequence of values for each numeric t value and then had to pick off a certain operand. It's also more robust since its not sensitive to positions (which could change due to a new lexicographic ordering if you altered the names of your variables).
The above took about 16 seconds on an Intel i7. That's not fast. One reason is that the numeric integrals are being computed to higher accuracy than is necessary for the plotting. So let's restart (to ensure fair timing) and recompute with relaxed tolerances on the numeric integrations done for a and b.
restart:
sys := diff(alpha(t),t) = -1/200*beta(t),
diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2:
ic := alpha(0)=0, beta(0)=-1:
p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):
alphat := eval(alpha(t),p):
betat := eval(beta(t),p):
a := unapply( exp( Int(alphat , 0..t, epsilon=1e-5) ), t, numeric):
b := unapply( exp( Int(betat , 0..t, epsilon=1e-5) ), t, numeric):
evalf(a(20.0)), evalf(b(20.0));
-18
5.347592681, 3.102018090 10
st := time():
P := plots:-odeplot(p, [[t, a(t)], [t, b(t)]], 0 .. 20,
thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;
0.921 seconds
You can check that this gives a plot that appears the same.
Now lets augment the example so that the numeric integrals are computed by dsolve,numeric itself. We can do that by using Calculus. In this way we are leaving it to the numeric ode solver to do its own error estimation, stepsize control, stiffness or singularity detection, etc.
Note that the integrands alphat and betat are not functions for which we have explicit functions -- their accuracy is intimately tied to the numerical ode solving. This is not quite the same as simplistically using a numerical ode routine to replace a numeric quadrature routine for a problem with an integrand which we expect to be computed directly to any desired accuracy (including on either side of any singularity).
restart:
sys := diff(alpha(t),t) = -1/200*beta(t),
diff(beta(t),t) = -1/200*alpha(t) - 1/Pi^2,
diff(g(t),t) = alpha(t), diff(h(t),t) = beta(t):
ic := alpha(0)=0, beta(0)=-1,
g(0)=0, h(0)=0:
p := dsolve({ic, sys}, numeric, method = rosenbrock, output=listprocedure):
alphat := eval(alpha(t),p):
betat := eval(beta(t),p):
gt := eval(g(t),p):
ht := eval(h(t),p):
exp(gt(20.0)), exp(ht(20.0));
-18
5.34759070530497, 3.10201330730572 10
st := time():
P := plots:-odeplot(p, [[t, exp(g(t))], [t, exp(h(t))]], 0 .. 20,
thickness = 2, numpoints = 50, color = [red, blue]):
( time() - st )*`seconds`;
0.031 seconds
P;