Mathematica在拟合微分方程组参数时耗尽内存

时间:2011-11-29 13:35:39

标签: memory memory-leaks wolfram-mathematica cache-control

当我尝试处理实验数据时,我在Mathematica中遇到了内存问题。我正在使用Mathematica找到三个偏微分方程组的最优参数。

e参数大于0.4时,Mathematica消耗了大量内存。对于e < 0.4,该计划正常运作。

我尝试过使用$HistoryLength = 0,并减少AccuracyGoalWorkingPrecision但没有成功。

我正在努力了解我犯了哪些错误,以及如何限制内存使用量。

Clear[T, L, e, v, q, C0, R, data, model];
T = 13200; 
L = 0.085; 
e = 0.41; 
v = 0.000557197; 
q = 0.1618; 
C0 = 0.0256; 
R = 0.00075;

data = {{L, 600, 0.141124587}, {L, 1200, 0.254134509}, {L, 1800, 
    0.342888644}, {L, 2400, 0.424476295}, {L, 3600, 0.562844542}, {L, 
    4800, 0.657111356}, {L, 6000, 0.75137817}, 
       {L, 7200, 0.815876516}, {L, 8430, 0.879823594}, {L, 9000, 
    0.900771775}, {L, 13200, 1}};

model[(De_)?NumberQ, (Kf_)?NumberQ, (Y_)?NumberQ] := 
 model[De, Kf, Y] =  yeld /. Last[Last[
     NDSolve[{
       v D[Ci[z, t], z] + D[Ci[z, t], t] == -((
         3 (1 - e) Kf (Ci[z, t] - C0))/(
         R e (1 - (R Kf (1 - R/r[z, t]))/De))),
       D[r[z, t], t] == (R^2 Kf (Ci[z, t] - C0))/(
        q r[z, t]^2 (1 - (R Kf (1 - R/r[z, t]))/De)),
       D[yeld[z, t], t] == Y*(v e Ci[z, t])/(L q (1 - e)),
       r[z, 0] == R,
       Ci[z, 0] == 0,
       Ci[0, t] == 0,
       yeld[z, 0] == 0},
      {r[z, t], Ci[z, t], yeld}, {z, 0, L}, {t, 0, T}]]]

fit = FindFit[
  data, {model[De, Kf, Y][z, t], {0.97  < Y < 1.03, 
    10^-6 < Kf < 10^-4, 10^-13 < De < 10^-9}}, 
     {{De, 10^-12}, {Kf,  10^-6}, {Y, 1}}, {z, t}, Method -> NMinimize]

data = {{600, 0.141124587}, {1200, 0.254134509}, {1800, 
    0.342888644}, {2400, 0.424476295}, {3600, 0.562844542}, {4800, 
    0.657111356}, {6000, 0.75137817}, {7200, 0.815876516}, 
       {8430, 0.879823594}, {9000, 0.900771775}, {13200, 1}}; 

YYY = model[De /. fit[[1]], Kf /. fit[[2]], Y /. fit[[3]]]; 

Show[Plot[Evaluate[YYY[L, t]], {t, 0, T}, PlotRange -> All], 
 ListPlot[data, PlotStyle -> Directive[PointSize[Medium], Red]]]

链接到.nb文件:http://www.4shared.com/folder/249TSjlz/_online.html

1 个答案:

答案 0 :(得分:3)

我有一种潜在的怀疑,为什么它失败的原因是因为你正在缓存结果。

您是否需要存储NDSolve正在生成的每个解决方案?我对Findfit这是否有用持怀疑态度,因为我非常怀疑它会重新审视过去的结果。

此外,它不像你在谈论你正在谈论的有限域的整数。您正在使用实数甚至超出您指定的范围,可能会有 A LOT 不同的解决方案。我认为你不想存储它们中的每一个。

重写您的代码,而不是:

model[(De_)?NumberQ, (Kf_)?NumberQ, (Y_)?NumberQ] := 
 model[De, Kf, Y] =  yeld /. Last[Last[
     NDSolve[..]

你改为:

model[(De_)?NumberQ, (Kf_)?NumberQ, (Y_)?NumberQ] := 
 NDSolve[..]

通过缓存你以前的结果,你会在FindFit之后吃掉没有明天的记忆。通常情况下,当你有一个递归关系时它很有用,但在这里我会认真反对它。


一些注释:

在我的机器上运行2415秒后,Mathematica的内存使用率从112,475,400个字节变为1,642,280,320个字节,并带有缓存。

我现在正在运行没有缓存的代码。