I am using the scipy.optimize.fsolve
function with the following code:
I am trying to solve the obj function for the value of x_1
keeping the value of x_2
constant. It should be noted that value of x_1
and x_2
are between 0 and 1.
I am adding the value of w_xx
, b_xx
and y_test
.
import numpy as np
from scipy.optimize import fsolve
y_test = np.array([3.448 ,11.071,3.602 ,11.838,3.512 ,13.78,4.013,15.209,3.339,13.15,3.387,17.419,3.793,15.303,3.92,11.683,3.655 ,14.317]).reshape(9,2)
#weight matrix
w_01 = np.array([0.5524624,0.72511494,0.51372594,-0.6308459]).reshape(2,2)
w_T2 = np.array([[-0.59752214, -0.5804831, 1.4108963, -0.2634158, -0.5614638, -1.0390981, 0.65243214, 0.7106961, -0.5652963, -0.0601576, 0.90772694, -1.3798463, -0.40833127, -0.7003734, -0.21786042, 0.27037245]]).reshape(2,8)
w_02 = np.transpose(w_T2)
w_03 = np.array([[-1.0097426,0.32732514,0.24015452,-1.0950012,0.24607354,-0.21128657,-0.89929247,0.5828309,-1.4573368,-1.0770408,0.62045175,-1.2865094,-1.3986484,-1.2846812, 0.9638692 ,1.5144163]]).reshape(2,8)
#Bais matrix
b_01 = np.array([0.859291,0.59829414]).reshape(2,1)
b_02 = np.array([-0.5619188,-0.57078356,0.5717453,-0.5602762,-0.61745477,-0.6130685,0.56874627,0.55697656]).reshape(8,1)
b_03 = np.array([0.23421602,0.48550755]).reshape(2,1)
def sigmoid(x):
return 1 / (1 + np.exp(-x))
### Defining Obj function
### inp is 2x1 matrix and out is also 2x1 matrix
def objfunction(x1,x2,y):
inp = np.array([x1,x2]).reshape(2,1)
out = y.reshape(2,1)
f = (np.dot(w_03,(np.dot(w_02,(sigmoid(np.dot(w_01,inp) + b_01))) + b_02)) + b_03) - out # value of y
return f.flatten()
### Calculating Solution
x_1 = 0 ### Inital guess
x_2 = 0.5
sol = np.zeros((len(y_test),2))
for i,value in enumerate(y_test):
sol[i] = fsolve(objfunction,x_1,args=(x_2,value))
Error:
p:\python\mimo_fsolve.py:46: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
inp = np.array([x1,x2]).reshape(2,1)
AttributeError: 'numpy.ndarray' object has no attribute 'exp'
loop of ufunc does not support argument 0 of type numpy.ndarray which has no callable exp method
To answer your main question, the reason you're getting this error is because fsolve
is providing objfunction
with a numpy array that looks like np.array([x1])
for x1
. When you try and combine this with x2
, which is a float, to make inp
, you create a ragged array since the first element is an array and the second element is just a number. Numpy doesn't like that so it turns the array into an object
data type. You can see this if you try the following code:
print(np.array([np.array([0]), 0]).dtype) # object
When you then try and do np.exp
on the object array (because inp
is an object data type, np.dot(w_01, inp) + b_01
will also be), numpy throws an error because there is no implementation for np.exp
on object arrays (reread the error and you'll see that that is what the error says).
To fix this, you can replace x1
in your inp
definition with x1[0]
. But you'll end up with another issue because you're returning f.flatten()
, which will be of shape (2,)
since it contains x2
while fsolve
was expecting the return to be (1,)
since that's what it gave the function. You can fix that by taking the first element (i.e. f.flatten()[0]
). The last issue is that you defined sol
to be (n,2)
, but you only seem to want to store x_1
, so just make it a 1D array.
def objfunction(x1, x2, y):
inp = np.array([x1[0], x2]).reshape(2, 1)
out = y.reshape(2, 1)
f = (np.dot(w_03, (np.dot(w_02, (sigmoid(np.dot(w_01, inp) + b_01))) +
b_02)) + b_03) - out # value of y
return f.flatten()[0]
x_1 = 0 # Inital guess
x_2 = 0.5
sol = np.zeros((len(y_test)))
for i, value in enumerate(y_test):
sol[i] = fsolve(objfunction, x_1, args=(x_2, value))