我给出了一个我试图实现的代码的简化示例
from scipy.integrate import solve_bvp
import numpy as np
p = [1, 2]
a = 0.5
num = 100
x = np.linspace(0, 1, num)
var = np.ones((1, int(num/2)))
for i in range(int(num/2)):
var[0, i] = i**2
def fun(x, y):
force = np.zeros_like(x)
force[x <= 1-a] = -((np.polyval(p, y[0]))[x <= 1-a])*np.interp(x, x, var)
return np.vstack((y[1], y[2], y[3], force))
def bc(ya, yb):
return np.array([ya[0], ya[1], yb[0]-1, yb[2]])
y_guess = 0*np.ones((4, x.size))
res = solve_bvp(fun,bc,x,y_guess)
字符串
我面临以下错误
ValueError: object too deep for desired array
型
我还想澄清的是,我已经将var矩阵构造为x^2,并希望使用np.interp
函数来用于我试图求解的实际四阶边值问题的强制项。我的强迫项是不连续的,由多值函数给出,x在(0,0.5)中,否则为零。删除interp函数可以使代码正常工作,但我无法找到包含此术语的正确方法。
1条答案
按热度按时间tzcvj98z1#
为了首先解决错误,
interp
需要三个参数:x
、xp
和fp
。xp
和fp
是你知道的x和y值,它们应该是一对一对应的1D数组。目前,var
的形状为(1,50)
,这不是1D,因此出现了“太深”错误。您可以修复此问题并将其更改为var.ravel()
,但随后会出现错误,即形状不匹配,因为x.shape = (100,)
和var.ravel().shape = (50,)
。无论哪种方式,我都会将您的代码更改为具有单独的函数来处理
f(y)
和var(x)
。现在,f(y)
实际上是不正确的,因为它实际上是x和y的函数,即f=f(x,y)
(sincef(x>a,y) = 0
).为了简单起见,我也将var(x)
称为g(x)
(vars
是一个Python关键字,所以我避免使用var
,因为它很接近)。您希望ODE调用这两个函数,因此可以将它们设为参数,并使用functools.partial
处理只需要x和y的函数的solve_bvp
。对于
f(x,y)
,我使用np.polynomial.Polynomial
创建多项式并调用它(注意:这类采用与np.polyval
相反顺序的系数,因此颠倒)。然后我将x > a
的点更新为0。对于
g(x)
,我只是使用了您提到的x**2
表单,但您可以根据需要更改此表单。但是,因为g(x)
只是x的函数,并且x是常数(您设置这些值),所以g(x)
(或x的任何函数)是常数,实际上不需要函数。下面是我将使用的
solve_bvp
代码,尽管sol.success
是False
,这可能是这个问题被编造出来的结果,没有任何有效的解决方案。字符串