Home > OS >  Type Error Warning keeps occurring in my code
Type Error Warning keeps occurring in my code

Time:10-21

In my python code, I keep getting the following error:

TypeError: No loop matching the specified signature and casting was found for ufunc svd_n

the code is as follows:

import numpy as np
from numpy.linalg import norm

def sdm_3eqs():
    def f_bold(x):
        return [15*x[0]   x[1]**2 - 4*x[2] - 15, x[0]**2   10*x[1] - x[2] - 10, x[1]**3 - 25*x[2]   24]
    
    def f(x):
        f_n = []
        for i in range(len(x)):
            f_i = f_bold[i]**2
            f_n.append(f_i)
    
        return np.sum(f_n)
    
    def M(x):
        m = np.array([[15, 2*x[0], 0], [2*x[1], 10, 3*x[1]**2], [-4, -1, -25]])
        return m
    
    def grad_f(x):
        return 2*M(x)*f_bold(x)
    
    def d(x):
        return -grad_f(x)/norm(grad_f(x), ord=2)
    
    def s_prime(x, alpha, d):
        return grad_f(x   alpha*d)*d
    
    x = [0.5, 0.5, 0.5]
    iter = 0
    err = 100

    while err > 0.005:
        x_k = x
        d_k = d(x_k)

        m = 0
        sprime = 300
        alpha_l = 0
        alpha_u = 1.5
        alpha = (alpha_l alpha_u)/2
        while abs(sprime) > 0.0005:
            alpha = (alpha_l alpha_u)/2
            sprime = s_prime(x_k, alpha, d_k)[0][0]

            if abs(sprime) < 0.001:
                break
            elif sprime > 0:
                alpha_u = alpha
            else:
                alpha_l = alpha
            
            m  = 1
        
        iter  = 1
        x = x_k   alpha*d_k
        err = norm(grad_f(x), ord=2)/max(1, norm(f_bold(x), ord=2))
    
    print(f'f_bold: {f_bold(x)}')

sdm_3eqs()

I am unsure why but it says the type error come from line 57 in the code:

err = norm(grad_f(x), ord=2)/max(1, norm(f_bold(x), ord=2))

If anyone can help, that would be great!

EDIT:

Traceback (most recent call last):
  File "/Users/aidanpayne/Desktop/Scripts/Python/University of Greenwich/MATH1157/Scripts/Steepest Descent Method.py", line 61, in <module>
    sdm_3eqs()
  File "/Users/aidanpayne/Desktop/Scripts/Python/University of Greenwich/MATH1157/Scripts/Steepest Descent Method.py", line 57, in sdm_3eqs
    err = norm(grad_f(x), ord=2)/max(1, norm(f_bold(x), ord=2))
  File "<__array_function__ internals>", line 5, in norm
  File "/Users/aidanpayne/opt/anaconda3/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 2579, in norm
    ret =  _multi_svd_norm(x, row_axis, col_axis, amax)
  File "/Users/aidanpayne/opt/anaconda3/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 2355, in _multi_svd_norm
    result = op(svd(y, compute_uv=False), axis=-1)
  File "<__array_function__ internals>", line 5, in svd
  File "/Users/aidanpayne/opt/anaconda3/lib/python3.8/site-packages/numpy/linalg/linalg.py", line 1673, in svd
    s = gufunc(a, signature=signature, extobj=extobj)
TypeError: No loop matching the specified signature and casting was found for ufunc svd_n

CodePudding user response:

It looks like the M(x) function is returning a 3-dimensional array, of structure

[
  [   a    [b c d]    e   ]
  [[f g h]    i    [k l m]]
  [   n       o       p   ]
]

and then you're attempting to matrix-multiply that with the result of f_bold(x) and calculate the norm.

I believe the error is related to trying to calculate the norm of this irregular matrix. In particular, check your function definition for M(x) to verify the shape/regularity of its returned array.

line 17: m = np.array([[15, 2*x[0], 0], [2*x[1], 10, 3*x[1]**2], [-4, -1, -25]])
                              ^^^^         ^^^^        ^^^^

CodePudding user response:

I added a couple of prints to your code, and got this run:

In [63]: sdm_3eqs()
<ipython-input-62-2b082fcea817>:14: 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.
  m = np.array([[15, 2*x[0], 0], [2*x[1], 10, 3*x[1]**2], [-4, -1, -25]])

f_bold
 [array([ 6.64610017e-05, -8.57391288e 00, -1.40877199e 01]), array([-3.81306816, -3.03705309, -6.81097338]), array([ 15.47764768,  12.41073581, -18.41883603])]

grad_f
 array([[0.0019938300511945783,
        array([-36.8081748 , -17.89173085, -17.14782575]), -0.0],
       [array([ -8.20903822, -10.93449844,  -7.0767119 ]),
        -60.74106175194817,
        array([-11.83793275, -21.00337307,  -8.79740011])],
       [-123.82118142652486, -24.821471626766595, 920.9418016830625]],
      dtype=object)


Traceback (most recent call last):
  File "<ipython-input-63-8732d4079184>", line 1, in <module>
    sdm_3eqs()
  File "<ipython-input-62-2b082fcea817>", line 57, in sdm_3eqs
    err = np.linalg.norm(grad_f(x), ord=2)/max(1, np.linalg.norm(f_bold(x), ord=2))
  File "<__array_function__ internals>", line 5, in norm
  File "/usr/local/lib/python3.8/dist-packages/numpy/linalg/linalg.py", line 2579, in norm
    ret =  _multi_svd_norm(x, row_axis, col_axis, amax)
  File "/usr/local/lib/python3.8/dist-packages/numpy/linalg/linalg.py", line 2355, in _multi_svd_norm
    result = op(svd(y, compute_uv=False), axis=-1)
  File "<__array_function__ internals>", line 5, in svd
  File "/usr/local/lib/python3.8/dist-packages/numpy/linalg/linalg.py", line 1672, in svd
    s = gufunc(a, signature=signature, extobj=extobj)
UFuncTypeError: Cannot cast ufunc 'svd_n' input from dtype('O') to dtype('float64') with casting rule 'same_kind'

In new enough numpy versions, the creation of a "ragged array" gets this warning, and tells us that we are not creating a simple numeric array. Instead M is an object dtype array, containing a mix of numbers and arrays.

f_bold is a list of arrays. grad_f is a (3,3) object dtype array with a mix of floats and arrays.

And in the latest numpy version this kind of error specifies the problem dtype - which as I suspected is 'O', object.

norm cannot handle that kind of array. That's why I asked for the dtype of the 2 norm arguments.

  • Related