首页 文章

在矢量化代码中scipy fsolve的速度

提问于
浏览
1

我有一个大小(254,80)的数组,我需要使用scipy的fsolve . 我发现在向量上使用fsolve的速度比for循环中的速度快,但仅适用于长达约100个值的向量 . 在此之后,速度迅速下降并变得非常慢,有时完全停止 .

我正在循环遍历数组的一个维度并在较小的维度上使用矢量化的fsolve,但它仍然比我期望/喜欢的时间更长 .

有没有人有这方面的好工作或知道一个类似的功能,将很乐意处理更大尺寸的矢量?或者也许如果我做错了什么......

这是当前的代码:

for i in range(array.shape[0]):
    f = lambda y: a[i] - m[i]*y - md[i]*(( y**4 + 2*(y**2)*np.cos(Thetas[i,:]) )**0.25)
    ystar[i,:] = fsolve(f, y0[i])

(其余变量都是相似的大小)

进一步深入研究,我发现了一个诸如此类的功能

f = lambda y: y*np.tanh(y) - a0/(m**2)

比解决更快

f = lambda y: (m**2)y*np.tanh(y) - a0

其中m和a0是大型2D np阵列 .

谁能解释为什么会这样?

谢谢,瑞秋

1 回答

  • 0

    虽然没有人回答我找到了一个避免使用fsolve功能并使用插值的解决方法 . 幸运的是,初始猜测足够好,只需要几个y值 . 如果最初的猜测知识很差,那么这种方法可能不合适 . 请注意,这仍有一些问题,但就我的目的而言,它表现良好......

    ystar = np.empty((A,B))     # empty array for the solutions   
        num_ys = 20 #number of points to find where the solution is 
        y0_u = y0 #just so the calculated initial guess isn't overwritten
        for i in range(Thetas.shape[1]):
            ys = np.linspace(-.05,.2,num_ys)[:,None]*np.ones((num_ys,Thetas.shape[0])) + y0_u
            vals = (np.squeeze(eta) - np.squeeze(m)*ys*np.sqrt(g*np.tanh(ys**2*depth)) - np.squeeze(md)*np.sqrt(g*np.tanh(depth*np.sqrt(ys**4+2*(ys**2)*kB*np.cos(Thetas[:,i]+phi_bi)+kB**2)))*(( ys**4+2*(ys**2)*kB*np.cos(Thetas[:,i]+phi_bi)+kB**2 )**0.25))
            idxs_important = -1*(np.clip(np.vstack(((np.sign(vals[:-1]*vals[1:])-1),np.zeros((1,Thetas[:,i].size)))),-1,0) + np.clip(np.vstack((np.zeros((1,Thetas[:,i].size)),(np.sign(vals[:-1]*vals[1:]))-1)),-1,0))
    
            ys_chosen = idxs_important*ys
            ys_chosen[ys_chosen==0] = 10000 
            sorted_ys_idx = np.argsort(ys_chosen.T, axis = 1)
            sorted_ys = ((ys_chosen.T)[np.arange(np.shape(ys_chosen.T)[0])[:,np.newaxis],sorted_ys_idx]).T
            sorted_vals = (((vals*idxs_important).T)[np.arange(np.shape(vals.T)[0])[:,np.newaxis],sorted_ys_idx]).T
        #    interpolation bit 
            x_id = 0
            yposs = sorted_ys[:2,:]
            valposs = sorted_vals[:2,:]
            y = yposs[0,:] + (yposs[1,:] - yposs[0,:])*(x_id - valposs[0,:])/(valposs[1,:] - valposs[0,:])
            ystar[:,i] = np.squeeze(y)
            y0_u=ystar[:,i]
    

相关问题