-3

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
Ask_delta
  • 3
  • 3
  • 1
    Please share a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). You dumped a bunch of code (some of which is not formatted correctly). You should simplify the code down to just the bare essentials of what produces the error. Also, please share the error message as text, not an image. – jared Jul 21 '23 at 18:23
  • Also, what does 2**1 shape mean? Do you mean (2,1) or 2x1? – jared Jul 21 '23 at 18:23
  • I wanted to write 2x1 but I made an error. I have edited my post based on your comment. Please write if its is in correct format. Thanks in advance – Ask_delta Jul 21 '23 at 19:27
  • Your example is now missing definitions for all the `w_xx` and `b_xx` terms as well as `y_test`. – jared Jul 21 '23 at 19:37
  • @jared I have updated the code with w_xx, b_ xx and y_test. I also run the code and I am getting the error written above. Thanks – Ask_delta Jul 21 '23 at 20:13
  • Are you looking to only store `x_1` in `sol` or both `x_1` and `x_2`? – jared Jul 21 '23 at 20:44
  • the important part of the error `ragged nested sequences`. – hpaulj Jul 21 '23 at 21:04
  • I wanted to store both `x_1` and `x_2` in `sol` but just storing value of `x_1` will work as well. – Ask_delta Jul 21 '23 at 21:11
  • @hpaulj if I understand your comment well. I changed the line in code from `np.array([x1,x2]).reshape(2,1)` to `np.array([x1,x2],dtype = float).reshape(2,1)`. As the `x_1` and `x_2` both have decimal values. But there were still errors. Please advice. Thanks in advance – Ask_delta Jul 21 '23 at 21:23
  • @hpaulj I saw that was the issue. I just wanted clarification on the desired result so I could figure out the right way to fix things. – jared Jul 21 '23 at 21:31

1 Answers1

1

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))
jared
  • 4,165
  • 1
  • 8
  • 31