我不是河畔e你想要做什麼
func(x + t*grad(x, A, b, c), A, b, c)
什麼是t
?
在任何情況下,你的fmin_cg
調用不正確 - 的fmin_cg
簽名
fmin_cg(f, x0, fprime=None, args=(), ...)
的第一個參數必須是你的目標函數,func
,第二需求是你最初的猜測x
,第三個(可選)參數是您的漸變函數grad
,第四個是附加參數的集合f
和fprime
(不包括x
)。
的調用應該是這樣的:
scipy.optimize.fmin_cg(func, x, fprime=grad, args=(A, b, c))
然而,這仍然不會因爲你的陣列尺寸的問題的工作:
<ipython-input-49-bf5fa71345fe> in grad(x, A, b, c)
1 def grad(x, A, b, c):
----> 2 gradient = A * (1.0/(b - A.transpose()*x)) + c
3 return gradient
4
/home/alistair/.venvs/core/local/lib/python2.7/site-packages/numpy/matrixlib/defmatrix.pyc in __mul__(self, other)
341 if isinstance(other, (N.ndarray, list, tuple)) :
342 # This promotes 1-D vectors to row vectors
--> 343 return N.dot(self, asmatrix(other))
344 if isscalar(other) or not hasattr(other, '__rmul__') :
345 return N.dot(self, other)
ValueError: shapes (500,100) and (1,100) not aligned: 100 (dim 1) != 1 (dim 0)
要弄清楚這是爲什麼發生,我們可以在grad
設置一個斷點:
import pdb
def grad(x, A, b, c):
pdb.set_trace()
gradient = A * (1.0/(b - A.transpose()*x)) + c
return gradient
在第一次調用grad
,我們看到:
(Pdb) type(x)
<type 'numpy.ndarray'>
(Pdb) !x.shape
(100,)
內的某處fmin_cg
,x
正在從(100, 1)
np.matrix
轉換爲(100,)
1D np.ndarray
。對於np.ndarray
,運算符執行元素乘法而不是矩陣乘法,這將失敗,因爲x
和A.transpose()
具有不兼容的維度。
基本上你是對的事實,np.matrix
尚未完全通過numpy的和SciPy的許多功能,包括預期的np.ndarray
支持的跑起來。我強烈建議您從使用np.matrix
切換到np.ndarray
- 使用np.matrix
爲officially discouraged,並且在不久的將來可能會被棄用。
你grad
功能可以改寫爲:
def grad(x, A, b, c):
gradient = A.dot(1.0/(b - A.T.dot(x))) + c
return gradient
...和你的初始參數爲:
np.random.seed(1234)
m = 500 #500
n = 100 #100
A = np.random.randint(low=-10, high=1, size=(n, m))
b = np.random.randint(low=500, high=1000, size=m)
c = np.random.randint(low=0.1, high=2, size=n)
x = np.random.randint(low=1, high=10, size=n)
...現在你到fmin_cg
調用應該工作:
res = scipy.optimize.fmin_cg(func, x, fprime=grad, args=(A, b, c))
由於您在函數中使用'np.dot',因此不要使用'np.asmatrix'使事情複雜化。堅持常規陣列。如果需要添加一個維度(使用'newaxis','reshape'或'atleast_2d')。 – hpaulj