Mathematica running EXTREMELY slow (freezes when plotting graphs for integrals)
Here is my take on this. Key points are the use of Evaluate
, to make sure that Integrate
is called only once and not every time d
is called, and the use of Assumptions
, where I took the liberty of assuming that k
is real.
I hope I didn't mix up the limits.
{f, m, r} = {68000, 2340, 68};
a[k_, t_] := f/(m + k - r t) - 10
d[k_] := Evaluate[
Integrate[a[k, t], {p, 0, k/r}, {t, 0, p},
Assumptions -> k \[Element] Reals]];
Plot[d[x], {x, 0, 10}]
For the other one,
r1 = 200;
a1[k_, t_] := f/(m + k - r1 t) - 10
d1[k_] :=
Evaluate[Integrate[a1[k, t], {p, 0, k/r1}, {t, 0, p},
Assumptions -> k \[Element] Reals]];
Plot[d1[x], {x, 0, 10}]
Try:
$Version
(* "11.2.0 for Microsoft Windows (64-bit) (September 11, 2017)" *)
ClearAll["Global`*"]; Remove["Global`*"];(* Clears All variables *)
f = 68000;
m = 2340;
r = 68;
a[k_?NumericQ, t_?NumericQ] := f/(m + k - r*t) - 10
v[k_?NumericQ, t_?NumericQ] := NIntegrate[a[k, p], {p, 0, t}, Method -> {Automatic, "SymbolicProcessing" -> 0}];
d[k_?NumericQ] := NIntegrate[v[k, p], {p, 0, k/r}, Method -> {Automatic, "SymbolicProcessing" -> 0}];
r1 := 200
a1[k_?NumericQ, t_?NumericQ] := f/(m + k - r1*t) - 10
v1[k_?NumericQ, t_?NumericQ] := NIntegrate[a1[k, p], {p, 0, t}, Method -> {Automatic, "SymbolicProcessing" -> 0}]
d1[k_?NumericQ] := NIntegrate[v1[k, p], {p, 0, k/r1}, Method -> {Automatic, "SymbolicProcessing" -> 0}]
Plot[{d[x], d1[x]}, {x, 0, 10}] // AbsoluteTiming
Aside from necessary Assumptions
mentioned in another answers, your problem is that you're abusing delayed assignment — the :=
operator. It results in the right-hand side being evaluated every time you call your function or use your variable — unless the right-hand side has been wrapped with Evaluate
function. I.e., Integrate
functions are re-evaluating the integrals each time you call your v
, d
, v1
and d1
functions.
The proper way, after adding the necessary Assumptions
for the integrals is to replace your :=
with =
— at least for the calls to Integrate
, although in your specific case you don't need delayed assignment at all, so you could simply replace all of the operators with immediate assignments.
Now, if you know that your variable $k$ in the whole computation satisfies $k\in\mathbb R$, then you can wrap the computation in Assuming
function or just set $Assumptions
variable to your assumption at the beginning. (Don't forget to reset the variable later to the default value of True
when you do unrelated calculations.)
After taking all this into account, your code could look like this:
f = 68000;
m = 2340;
r = 68;
r1 = 200;
a[k_, t_] = f/(m + k - r*t) - 10;
a1[k_, t_] = f/(m + k - r1*t) - 10;
Assuming[Element[k, Reals],
v[k_, t_] = Integrate[a[k, p], {p, 0, t}];
d[k_] = Integrate[v[k, p], {p, 0, k/r}];
v1[k_, t_] = Integrate[a1[k, p], {p, 0, t}];
d1[k_] = Integrate[v1[k, p], {p, 0, k/r1}];
Plot[{d[x], d1[x]}, {x, 0, 10}]
]
More on :=
and =
assignments see in Immediate and Delayed Definitions tutorial.