使用 ParametricNDSolve 迭代 运行 通过参数集列表
Iteratively running through list of parameter sets with ParametricNDSolve
所以我有下面的代码
perturb1 =
x'[t] == mu1*x[t] + x[t]*(a*x[t] + b*y[t] + c*z[t]) +
x[t]*eps1 * (UnitStep[t - 1.5] - UnitStep[t - 2.5]);
perturb2 =
y'[t] == mu2*y[t] + y[t]*(d*x[t] + e*y[t] + f*z[t]) +
y[t]*eps2 * (UnitStep[t - 1.5] - UnitStep[t - 2.5]);
perturb3 =
z'[t] == mu3*z[t] + z[t]*(g*x[t] + h*y[t] + i*z[t]) +
z[t]*eps3 * (UnitStep[t - 1.5] - UnitStep[t - 2.5]);
perturbSol = ParametricNDSolve[
{perturb1, perturb2, perturb3, x[0] == 0.25, y[0] == 0.4,
z[0] == 0.35},
{x[t], y[t], z[t]},
{t, 0, 500},
{mu1, mu2, mu3, a, b, c, d, e, f, g, h, i, eps1, eps2, eps3}
];
Evaluate[x[t][#] /. perturbSol] & /@ parameterSets
parameterSets
是一个包含 5000 多个元素的列表,其形式为 {mu1, mu2, mu3, a, b, c, d, e, f, g, h, i, eps1, eps2, eps3 } (但带有数值)。我要做的是使用每个参数集评估参数函数。当我像上面那样做时,我得到了错误
ParametricNDSolve: Too many parameters in {mu1,mu2,mu3,a,b,c,d,e,f,g,h,i,eps1,eps2,eps3} to be filled from {{0.9,0.9,0.9,-2,-1,-1,-1,-2,-1,-1,-1,-2,-2,-2,-2}}.
这似乎是因为,对于单个值,您将按如下方式计算函数:
Evaluate[x[t][0.9,0.9,0.9,-2,-1,-1,-1,-2,-1,-1,-1,-2,-2,-2,-2]/.perturbSol]
而在 parameterSets 上使用 Map 时,它会这样做:
Evaluate[x[t][{0.9,0.9,0.9,-2,-1,-1,-1,-2,-1,-1,-1,-2,-2,-2,-2}]/.perturbSol]
即它将函数应用于 15 个参数的列表,而不是用逗号分隔的 15 个参数。
有什么优雅的解决方法吗?我尝试在 # 周围展平,但没有做任何事情(正如我所预料的那样)。我想一种方法是在方括号中写#1、#2、#3 等,但这很乱。
有更好的方法吗?
非常感谢,
H
可能,您想要类似
的东西
u = ParametricNDSolveValue[{perturb1, perturb2, perturb3,
x[0] == 0.25, y[0] == 0.4, z[0] == 0.35}, {x, y, z}, {t, 0,
500}, {mu1, mu2, mu3, a, b, c, d, e, f, g, h, i, eps1, eps2,
eps3}];
parameterSets = RandomReal[{-1, 1}, {3, 15}];
(u[##])[[1]][t] & @@@ parameterSets
所以我有下面的代码
perturb1 =
x'[t] == mu1*x[t] + x[t]*(a*x[t] + b*y[t] + c*z[t]) +
x[t]*eps1 * (UnitStep[t - 1.5] - UnitStep[t - 2.5]);
perturb2 =
y'[t] == mu2*y[t] + y[t]*(d*x[t] + e*y[t] + f*z[t]) +
y[t]*eps2 * (UnitStep[t - 1.5] - UnitStep[t - 2.5]);
perturb3 =
z'[t] == mu3*z[t] + z[t]*(g*x[t] + h*y[t] + i*z[t]) +
z[t]*eps3 * (UnitStep[t - 1.5] - UnitStep[t - 2.5]);
perturbSol = ParametricNDSolve[
{perturb1, perturb2, perturb3, x[0] == 0.25, y[0] == 0.4,
z[0] == 0.35},
{x[t], y[t], z[t]},
{t, 0, 500},
{mu1, mu2, mu3, a, b, c, d, e, f, g, h, i, eps1, eps2, eps3}
];
Evaluate[x[t][#] /. perturbSol] & /@ parameterSets
parameterSets
是一个包含 5000 多个元素的列表,其形式为 {mu1, mu2, mu3, a, b, c, d, e, f, g, h, i, eps1, eps2, eps3 } (但带有数值)。我要做的是使用每个参数集评估参数函数。当我像上面那样做时,我得到了错误
ParametricNDSolve: Too many parameters in {mu1,mu2,mu3,a,b,c,d,e,f,g,h,i,eps1,eps2,eps3} to be filled from {{0.9,0.9,0.9,-2,-1,-1,-1,-2,-1,-1,-1,-2,-2,-2,-2}}.
这似乎是因为,对于单个值,您将按如下方式计算函数:
Evaluate[x[t][0.9,0.9,0.9,-2,-1,-1,-1,-2,-1,-1,-1,-2,-2,-2,-2]/.perturbSol]
而在 parameterSets 上使用 Map 时,它会这样做:
Evaluate[x[t][{0.9,0.9,0.9,-2,-1,-1,-1,-2,-1,-1,-1,-2,-2,-2,-2}]/.perturbSol]
即它将函数应用于 15 个参数的列表,而不是用逗号分隔的 15 个参数。
有什么优雅的解决方法吗?我尝试在 # 周围展平,但没有做任何事情(正如我所预料的那样)。我想一种方法是在方括号中写#1、#2、#3 等,但这很乱。
有更好的方法吗?
非常感谢,
H
可能,您想要类似
的东西u = ParametricNDSolveValue[{perturb1, perturb2, perturb3,
x[0] == 0.25, y[0] == 0.4, z[0] == 0.35}, {x, y, z}, {t, 0,
500}, {mu1, mu2, mu3, a, b, c, d, e, f, g, h, i, eps1, eps2,
eps3}];
parameterSets = RandomReal[{-1, 1}, {3, 15}];
(u[##])[[1]][t] & @@@ parameterSets