首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >(c_eq,c_ieq) ValueError:所有输入数组必须具有相同的维数

(c_eq,c_ieq) ValueError:所有输入数组必须具有相同的维数
EN

Stack Overflow用户
提问于 2019-09-20 02:08:43
回答 2查看 660关注 0票数 1

我是scipy.optimize的新手,在看了它的教程和参考之后,我仍然不明白我在代码中做错了什么。我读过这篇文章,也不明白:Scipy optimize.minimize function

这里D是M*N矩阵,y是M*1矩阵。X应该是一个N*1矩阵(因为我需要计算它)。我需要最小化x中的L2范数,确保x中的每个元素都大于0。也须遵守Dx=y。最后:

极小维x_x_2

Dx=y

x>=0

代码语言:javascript
运行
复制
import scipy
from numpy import *

def square_sum(x):
    #x must be 1*N?
    x = x.reshape(len(x),1)
    y = dot(x.T,x)
    return y

def lessObsConstrain(x,D,y):
    #Dy=x equals (Dy-x)^2=0
    temp = y - dot(D,x.reshape(len(x),1))
    temp = temp.reshape(1,len(temp))
    return dot(temp,temp.T)

x0=ones((D.shape[1],))
result = scipy.optimize.minimize(square_sum, x0, args=(), method='SLSQP', jac=None, bounds=scipy.optimize.Bounds(0, 1), constraints=[{'type':'eq','fun':lessObsConstrain,'args':(D,y)}], tol=None, callback=None, options={'maxiter': 100, 'ftol': 1e-06, 'iprint': 1, 'disp': False, 'eps': 1.4901161193847656e-08})

但我知道这个错误:

c=串联((c_eq,c_ieq)) ValueError中,_minimize_slsqp c=串联((c_eq,c_ieq)) ValueError:所有输入数组必须具有相同的维数

谁能告诉我怎么改正我的代码吗?

EN

回答 2

Stack Overflow用户

发布于 2019-09-20 21:08:07

我找到了一种很难看的方法来传递这个错误。结果表明,1*1矩阵不同于标量矩阵。所以问题是数据维。

代码语言:javascript
运行
复制
import scipy
from numpy import *

def square_sum(x):
    return dot(x,x)

def lessObsConstrain(x,D,y):
    temp = y - dot(D,x.reshape(len(x),1))
    temp = temp.reshape(1,len(temp))
    return asscalar(dot(temp,temp.T))

x0=ones((D.shape[1],))
result = scipy.optimize.minimize(square_sum, x0, args=(), method='SLSQP', jac=None, bounds=scipy.optimize.Bounds(0, 1), constraints=[{'type':'eq','fun':lessObsConstrain,'args':(D,y)}], tol=None, callback=None, options={'maxiter': 100, 'ftol': 1e-06, 'iprint': 1, 'disp': False, 'eps': 1.4901161193847656e-08})
票数 1
EN

Stack Overflow用户

发布于 2019-09-22 19:36:27

代码语言:javascript
运行
复制
In [37]: from scipy import optimize                                             

虚拟数组,只用于测试形状:

代码语言:javascript
运行
复制
In [39]: D = np.eye(4,3); y = np.ones((4,1))                                    
In [40]: D                                                                      
Out[40]: 
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.],
       [0., 0., 0.]])
In [41]: y                                                                      
Out[41]: 
array([[1.],
       [1.],
       [1.],
       [1.]])
In [42]: x0 = np.ones((D.shape[1],))      

您的最新功能:

代码语言:javascript
运行
复制
In [57]: def square_sum(x): 
    ...:     return np.dot(x,x) 
    ...:  
    ...: def lessObsConstrain(x,D,y): 
    ...:     temp = y - np.dot(D,x.reshape(len(x),1)) 
    ...:     temp = temp.reshape(1,len(temp)) 
    ...:     return np.asscalar(np.dot(temp,temp.T)) 

在最初的版本中,它们都产生了2d数组:

代码语言:javascript
运行
复制
In [44]: square_sum(x0)                                                         
Out[44]: array([[3.]])
In [45]: lessObsConstrain(x0,D,y)                                                                  
Out[45]: array([[1.]])

约束处理程序抱怨说它无法加入等式和不等式约束(我不确定它到底在连接什么):

代码语言:javascript
运行
复制
c = concatenate((c_eq, c_ieq))

ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)

使用asscalar时,lessObsConstrain是标量的,并且连接可以工作。

代码语言:javascript
运行
复制
In [60]: optimize.minimize(square_sum, x0, args=(), method='SLSQP', jac=None, bo
    ...: unds=optimize.Bounds(0, 1), constraints=[{'type':'eq','fun':lessObsCons
    ...: train,'args':(D,y)}], tol=None, callback=None, options={'maxiter': 100,
    ...:  'ftol': 1e-06, 'iprint': 1, 'disp': False, 'eps': 1.4901161193847656e-
    ...: 08})                                                                   
/usr/local/bin/ipython3:7: DeprecationWarning: np.asscalar(a) is deprecated since NumPy v1.16, use a.item() instead

Out[60]: 
     fun: 2.9994000807884227
     jac: array([1.99980003, 1.99980003, 1.99980003])
 message: 'Positive directional derivative for linesearch'
    nfev: 218
     nit: 20
    njev: 16
  status: 8
 success: False
       x: array([0.99990001, 0.99990001, 0.99990001])

我推荐的是一个简单的dot,它不需要整形。但是y也需要1d (如x0):

代码语言:javascript
运行
复制
In [61]: def square_sum(x): 
    ...:     return np.dot(x,x) 
    ...:  
    ...: def lessObsConstrain(x,D,y): 
    ...:     #Dy=x equals (Dy-x)^2=0 
    ...:     temp = y - np.dot(D,x) 
    ...:     return np.dot(temp,temp) 
In [62]: y = np.ones((4))

最小化调用会产生相同的结果:

代码语言:javascript
运行
复制
In [56]: optimize.minimize(square_sum, x0, args=(), method='SLSQP', jac=None, bo
    ...: unds=optimize.Bounds(0, 1), constraints=[{'type':'eq','fun':lessObsCons
    ...: train,'args':(D,y)}], tol=None, callback=None, options={'maxiter': 100,
    ...:  'ftol': 1e-06, 'iprint': 1, 'disp': False, 'eps': 1.4901161193847656e-
    ...: 08})                                                                   
Out[56]: 
     fun: 2.9994000807884227
     jac: array([1.99980003, 1.99980003, 1.99980003])
 message: 'Positive directional derivative for linesearch'
    nfev: 218
     nit: 20
    njev: 16
  status: 8
 success: False
       x: array([0.99990001, 0.99990001, 0.99990001])

更仔细地查看lessObsConstrain。第一个点产生一个大小为M的数组(MxN与N):

代码语言:javascript
运行
复制
In [62]: np.dot(D,x0)                                                           
Out[62]: array([1., 1., 1., 0.])
In [63]: y       # (N,1)                                                                  
Out[63]: 
array([[1.],
       [1.],
       [1.],
       [1.]])
In [65]: lessObsConstrain(x0,D,y)                                               
Out[65]: 
array([[0., 0., 0., 1.],
       [0., 0., 0., 1.],
       [0., 0., 0., 1.],
       [0., 0., 0., 1.]])

(N,1)用(N,N)广播以产生(N,N)。如果y为(N,),则temp为1d,其dot为标量:

代码语言:javascript
运行
复制
In [66]: lessObsConstrain(x0,D,np.ones((4,)))                                   
Out[66]: 1.0

dot将A的最后一个轴与B的最后一个轴结合在一起,但是对于一维数组,它是标量矢量点,震级:

代码语言:javascript
运行
复制
In [67]: np.dot(np.arange(3),np.arange(3))                                      
Out[67]: 5
In [68]: np.dot(np.arange(3)[:,None],np.arange(3)[None,:])                      
Out[68]: 
array([[0, 0, 0],     # (3,1) with (1,3) => (3,3)
       [0, 1, 2],
       [0, 2, 4]])
In [69]: np.dot(np.arange(3)[None,:],np.arange(3)[:,None])                      
Out[69]: array([[5]])    # (1,3) with (3,1) => (1,1)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58020888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档