How to fix an Adam's method? - algorithm

I've such errors:
Coordinate .. is not a floating-point number
and can't correctly fix it.
The program works correctly for a function 1 - t *y , but not for y*y*Exp[t] - 2*y.
I will be really happy if you tell me why and how to fix this problem.
ABM[a0_, b0_, \[Alpha]_, m0_] :=
Module[{a = a0, b = b0, F, j, k, m = m0, p},
h = (b - a)/m; T = Table[a, {m + 1}];
Y = Table[\[Alpha], {m + 1}];
For[j = 1, j <= 3, j++, Subscript[k, 1] = h*f[T[[j]], Y[[j]]];
Subscript[k, 2] = h*f[T[[j]] + h/2, Y[[j]] + Subscript[k, 1]/2];
Subscript[k, 3] = h*f[T[[j]] + h/2, Y[[j]] + Subscript[k, 2]/2];
Subscript[k, 4] = h*f[T[[j]] + h, Y[[j]] + Subscript[k, 3]];
Y[[j + 1]] = Y[[j]] + (1/6)*(Subscript[k, 1] + 2*Subscript[k, 2] +
2*Subscript[k, 3] + Subscript[k, 4]);
T[[j + 1]] = a + h*j; ];
Subscript[F, 0] = f[T[[1]], Y[[1]]]; Subscript[F, 1] =
f[T[[2]], Y[[2]]]; Subscript[F, 2] = f[T[[3]], Y[[3]]];
Subscript[F, 3] = f[T[[4]], Y[[4]]]; For[j = 4, j <= m, j++,
p = Y[[j]] + (h/24)*(-9*Subscript[F, 0] + 37*Subscript[F, 1] -
59*Subscript[F, 2] + 55*Subscript[F, 3]);
T[[j + 1]] = a + h*j;
p = Y[[j]] + (h/24)*(Subscript[F, 1] -
5*Subscript[F, 2] + 19*Subscript[F, 3] +
9*f[T[[j + 1]], p]);
Y[[j + 1]] = p; Subscript[F, 0] = Subscript[F, 1];
Subscript[F, 1] = Subscript[F, 2]; Subscript[F, 2] =
Subscript[F, 3];
Subscript[F, 3] = f[T[[j + 1]], Y[[j + 1]]]; ];
Return[Transpose[{T, Y}]]];
f[t_, y_] = y*y*Exp[t] - 2*y;
Print["Find numerical solutions to the D.E."];
Print["y' = ", f[t, y]];
n = 25;
pts1 = ABM[0, 8, 2., n];
Y1 = Y;
Needs["Graphics`Colors`"];
graph1 = ListPlot[pts1, PlotJoined -> True, PlotStyle -> Green,
PlotRange -> {{0, 10}, {0, 10}}];
Print["The Adams-Bashforth-Moulton solution for y' = ", f[t, y]];
Print["Using n = ", n + 1, " points."];
Print[pts1];
Print[""];
Print["The final value is y(5) = ", Subscript[y, n + 1], " = ",
Y[[n + 1]]];

Related

Working with implicit functions in Mathematica returned from other functions

I have a equation
inv = (x + f) (y + g) == z;
But for some reason I cannot CountourPlot it, even though copy-pasting output, for example {(2 + x) (2 + y)} == {11} into CountourPlot works. I've tried both Hold and Defer to no luck.
What's happening and how I can fix this problem?
Actual code:
inv00 = (x + 1) (y + 1) == z
inv01 = inv00 /. {z -> 2}
ContourPlot[inv01, {x, 0, 1}, {y, 0, 1}]
ContourPlot[(1 + x) (1 + y) == 2, {x, 0, 1}, {y, 0, 1}]

how can I change value of array in a loop in mathematica?

I wrote a code in matlab as below:
T= ((1-(-1)) * rand([4,4],'double') + (-1) * ones(4,4));
for i=1:4
for j=1:i
T(j,i)=TT(i,j);
end
T(i,i)=0;
end
Now, I want to write this code in mathematica as below:
T = RandomReal[{-1, 1}, {4, 4}];
For[i = 1, i < 5, i++,
For[ j = 1, j < i, j++,
T[[j, i]] = T[[i, j]]]
T[[i, i]] = 0];
But it doesn't work!
Could you tell me about my mistakes?
Thank you.
SeedRandom[1234];
t = u = RandomReal[{-1, 1}, {4, 4}];
t // MatrixForm
If must use For
For[i = 1, i < 5, i++,
For[j = 1, j < i, j++, t[[j, i]] = t[[i, j]]]; t[[i, i]] = 0];
It mutates t
t // MatrixForm
One way to do this functionally
(l = LowerTriangularize[u, -1]) + Transpose[l]

How to obtain partial derivative symbol in mathematica

I would like Mathematica to return symbolic partial derivative instead of actual derivative.
StressMatrix = ( {
{\[Sigma]11, \[Sigma]12, \[Sigma]13},
{\[Sigma]21, \[Sigma]22, \[Sigma]23},
{\[Sigma]31, \[Sigma]32, \[Sigma]33}
} );
varList = ( {
{\[Rho], \[Theta], z}
} )
StressMatrix[[2, 3]]
varList[[1, 1]]
D[StressMatrix[[2, 3]], varList[[1, 1]]]
The code above returns zero but I would like it to return symbolically Partial derivative of Sigma[[2,3]] with respect to rho.
How can I do this?
You can use Inactivate,
Inactivate[D[StressMatrix[[2, 3]], varList[[1, 1]]]]
or Hold
Hold[D[StressMatrix[[2, 3]], varList[[1, 1]]]]
Various methods, including specified values (which need to be set after hold).
Clear[σ23]
StressMatrix = Map[Hold,
{{σ11, σ12, σ13}, {σ21, σ22, σ23}, {σ31, σ32, σ33}}, {2}];
varList = {{ρ, θ, z}};
σ23 = 4 ρ^2;
expr = StandardForm[
"∂" <> StringTake[ToString[StressMatrix[[2, 3]]], {6, -2}]/
"∂" <> ToString[varList[[1, 1]]]];
symbolic = Inactive[D][ReleaseHold#StressMatrix[[2, 3]], varList[[1, 1]]];
result = D[ReleaseHold#StressMatrix[[2, 3]], varList[[1, 1]]];
Row[{expr, " = ", symbolic, " = ", result}]
Alternatively
symbolic2 = StringJoin["D[",
StringTake[ToString[StressMatrix[[2, 3]]], {6, -2}], ",",
ToString#varList[[1, 1]], "]"];
Row[{expr, " = ", symbolic2, " = ", ToExpression[symbolic2]}]
And finally
Clear[σ23]
StressMatrix =
Map[HoldForm, {{σ11, σ12, σ13}, {σ21, σ22, σ23}, {σ31, σ32, σ33}}, {2}];
varList = {{ρ, θ, z}};
σ23 = 4 ρ^2;
expr = StandardForm[
"∂" <> ToString[StressMatrix[[2, 3]]]/
"∂" <> ToString[varList[[1, 1]]]];
symbolic = Inactive[D][ToString#StressMatrix[[2, 3]], varList[[1, 1]]];
result = D[ReleaseHold#StressMatrix[[2, 3]], varList[[1, 1]]];
Row[{expr, " = ", symbolic, " = ", result}]

Can i return list in Mathematica function?

In my code I'm trying to return list of numbers from my function but it gives me just null.
sifra[zprava_, klic_] := Module[
{c, n, e, m, i, z, pocCyklu, slovo},
pocCyklu = Ceiling[Divide[StringLength[zprava], 5]];
c = Array[{}, pocCyklu];
z = Partition[Characters[zprava], 5, 5, 1, {}];
For[i = 1, i < pocCyklu + 1, i++,
slovo = StringJoin # z[[i]];
m = StringToInteger[slovo];
n = klic[[1]];
e = klic[[2]];
c[[i]] = PowerMod[m, e, n];
]
Return[c]
];
sif = sifra[m, verejny]
After the cycles are done there should be 2 numbers in c.
Print[c] works OK it prints list with 2 elements in it but sif is null.
Return[c] gives me:
Null Return[{28589400926821874625642026431141504822, 2219822858062194181357669868096}]
You could write the function like this:
sifra[zprava_, klic_] := Module[{c, n, e, m, i, z, pocCyklu, slovo},
pocCyklu = Ceiling[Divide[StringLength[zprava], 5]];
c = ConstantArray[{}, pocCyklu];
z = Partition[Characters[zprava], 5, 5, 1, {}];
For[i = 1, i < pocCyklu + 1, i++,
slovo = StringJoin#z[[i]];
m = ToExpression[slovo];
{n, e} = klic;
c[[i]] = PowerMod[m, e, n]];
c]
Demonstrating use with example data:
sifra["9385637605763057836503784603456", {124, 2}]
{20, 97, 41, 9, 4, 113, 36}
You could also write the function like this:
sifra[zprava_, {n_, e_}] := Module[{z},
z = Partition[Characters[zprava], 5, 5, 1, {}];
Map[PowerMod[ToExpression[StringJoin[#]], e, n] &, z]]

How to draw three-dimensional image: Plot3D NDSolve

m = 10; c = 2; k = 5; F = 12;
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
{f, 0, 5} ( 0=< f <= 5 )
How to draw three-dimensional image:
x = u(t,f)
............
If f = 0.1,0.2,... 5,
We can solve the equation:
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
x is a function of t and f
...............
m = 10; c = 2; k = 5; F = 12;
f = 0.1
s = NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
Plot[Evaluate[x[t] /. s], {t, 0, 30}, PlotRange -> All]
f = 0.1
f = 0.2
f = 0.3
f = 5
How to draw three-dimensional image:
x = u(t,f)
Here goes a solution.
m = 10; c = 2; k = 5; F = 12;
NumberOfDiscrit$f = 20;(* Number of points you want to divide 0<=f<=5*)
NumberOfDiscrit$t = 100;(* Number of points you want to divide 0<=t<=30 *)
fValues = Range[0., 5., 5./(NumberOfDiscrit$f - 1)];
tValues = Range[0., 30., 30./(NumberOfDiscrit$t - 1)];
res = Map[(x /.
First#First#
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*#*t])*x[t] ==
F*Sin[2*Pi*#*t], x[0] == 0, x'[0] == 0}, x, {t, 0, 30}]) &,
fValues];
AllDat = Map[(##tValues) &, res];
InterpolationDat =
Flatten[Table[
Transpose#{tValues,
Table[fValues[[j]], {i, 1, NumberOfDiscrit$t}],
AllDat[[j]]}, {j, 1, NumberOfDiscrit$f}], 1];
Final3DFunction = Interpolation[InterpolationDat];
Plot3D[Final3DFunction[t, f], {t, 0, 30}, {f, 0, 5}, PlotRange -> All,
PlotPoints -> 60, MaxRecursion -> 3, Mesh -> None]
You can use Manipulate to dynamically change some of the parameters. By the way the above 3D picture may be misleading if one takes f as a continuous variable in u(t,f). You should note that the numerical solution seems to blow up for asymptotic values of t>>30. See the picture below.
Hope this helps you out.
You could also do something like this
Clear[f]
m = 10; c = 2; k = 5; F = 12;
s = NDSolve[{m*Derivative[2, 0][x][t, f] +
c*Derivative[1, 0][x][t, f] + (k*Sin[2*Pi*f*t])*x[t, f] == F*Sin[2*Pi*f*t],
x[0, f] == 0,
Derivative[1, 0][x][0, f] == 0}, x, {t, 0, 30}, {f, 0, .2}]
Plot3D[Evaluate[x[t, f] /. s[[1]]], {t, 0, 30}, {f, 0, .2}, PlotRange -> All]
This should do it.
m = 10; c = 2; k = 5; F = 12;
fun[f_?NumericQ] :=
Module[
{x, t},
First[x /.
NDSolve[
{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0},
x, {t, 0, 30}
]
]
]
ContourPlot[fun[f][t], {f, 0, 5}, {t, 0, 30}]
Important points:
The pattern _?NumericQ prevents fun from being evaluated for symbolc arguments (think fun[a]), and causing NDSolve::nlnum errors.
Since NDSolve doesn't appear to localize its function variable (t), we needed to do this manually using Module to prevent conflict between the t used in NDSolve and the one used in ContourPlot. (You could use a differently named variable in ContourPlot, but I think it was important to point out this caveat.)
For a significant speedup in plotting, you can use memoization, as pointed out by Mr. Wizard.
Clear[funMemo] (* very important!! *)
funMemo[f_?NumericQ] :=
funMemo[f] = Module[{x, t},
First[x /.
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] ==
F*Sin[2*Pi*f*t], x[0] == 0, x'[0] == 0}, x, {t, 0, 30}]]]
ContourPlot[funMemo[f][t], {f, 0, 5}, {t, 0, 30}] (* much faster than with fun *)
If you're feeling adventurous, and willing to explore Mathematica a bit more deeply, you can further improve this by limiting the amount of memory the cached definitions are allowed to use, as I described here.
Let's define a helper function for enabling memoization:
SetAttributes[memo, HoldAll]
SetAttributes[memoStore, HoldFirst]
SetAttributes[memoVals, HoldFirst]
memoVals[_] = {};
memoStore[f_, x_] :=
With[{vals = memoVals[f]},
If[Length[vals] > 100, f /: memoStore[f, First[vals]] =.;
memoVals[f] ^= Append[Rest[memoVals[f]], x],
memoVals[f] ^= Append[memoVals[f], x]];
f /: memoStore[f, x] = f[x]]
memo[f_Symbol][x_?NumericQ] := memoStore[f, x]
Then using the original, non-memoized fun function, plot as
ContourPlot[memo[fun][f][t], {f, 0, 5}, {t, 0, 30}]

Resources