Предупреждение об ошибке ввода продолжает появляться в моем коде

#python #numpy

Вопрос:

В моем коде python я продолжаю получать следующую ошибку:

Ошибка типа: Для ufunc svd_n не найдено цикла, соответствующего указанной подписи и приведению

код выглядит следующим образом:

 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 gt; 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) gt; 0.0005:  alpha = (alpha_l alpha_u)/2  sprime = s_prime(x_k, alpha, d_k)[0][0]   if abs(sprime) lt; 0.001:  break  elif sprime gt; 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()  

Я не уверен, почему, но в нем говорится, что ошибка типа происходит из строки 57 в коде:

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

Если кто-нибудь может помочь, это было бы здорово!

Редактировать:

 Traceback (most recent call last):  File "/Users/aidanpayne/Desktop/Scripts/Python/University of Greenwich/MATH1157/Scripts/Steepest Descent Method.py", line 61, in lt;modulegt;  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 "lt;__array_function__ internalsgt;", 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 "lt;__array_function__ internalsgt;", 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  

Комментарии:

1. Покажите полную обратную связь. Я не вижу svd_n вызова функции в вашем коде, но обратная связь должна сообщить нам, как это вызывается. Затем вам нужно проверить тип и тип dtype аргументов этой функции, чтобы увидеть, что отличается от документации.

2. Я отредактировал его.

3.Так что это один из norm звонков. В чем shape dtype смысл этих аргументов: grad_f(x) f_bold(x)

4. Не удалось показать dtype, но формы: Форма grad_f = (3, 3); форма f_bold = ()

5. Я думаю, что есть проблема с тем, что возвращает ваша функция grad_f; проверьте, соответствуют ли ваши выходные данные этой функции ожидаемым выходам (с точки зрения формы/структуры).

Ответ №1:

Похоже M(x) , что функция возвращает трехмерный массив структуры

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

а затем вы пытаетесь умножить это на матрицу с результатом f_bold(x) и вычислить норму.

Я полагаю, что ошибка связана с попыткой вычислить норму этой нерегулярной матрицы. В частности, проверьте определение своей функции M(x) , чтобы проверить форму/регулярность возвращаемого массива.

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

Ответ №2:

Я добавил пару отпечатков в ваш код и запустил это:

 In [63]: sdm_3eqs() lt;ipython-input-62-2b082fcea817gt;: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 "lt;ipython-input-63-8732d4079184gt;", line 1, in lt;modulegt;  sdm_3eqs()  File "lt;ipython-input-62-2b082fcea817gt;", 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 "lt;__array_function__ internalsgt;", 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 "lt;__array_function__ internalsgt;", 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'  

В достаточно новых версиях numpy создание «неровного массива» получает это предупреждение и сообщает нам, что мы не создаем простой числовой массив. Вместо M этого используется массив dtype объекта, содержащий сочетание чисел и массивов.

f_bold представляет собой список массивов. grad_f представляет собой массив dtype объекта (3,3) со смесью поплавков и массивов.

И в последней версии numpy такого рода ошибка указывает тип проблемы dtype, который, как я подозревал, является объектом «O».

norm не может обрабатывать массив такого рода. Вот почему я попросил dtype один из 2 norm аргументов.

Ответ №3:

Я решил эту проблему.

В некоторых функциях предполагалось, что это точечное произведение двух матриц.

напр.:

 def grad_f(x):  return 2*np.dot(M(x), f_bold(x))  

Вот обновленный код:

 import numpy as np from numpy.core.fromnumeric import shape from numpy.linalg import norm from numpy import transpose from numpy import array from numpy import sum from matplotlib import pyplot as plt  def sdm_3eqs():  def f_bold(x):  x_1 = x[0]  x_2 = x[1]  x_3 = x[2]  return array([15*x_1   x_2**2 - 4*x_3 - 15, x_1**2   10*x_2 - x_3 - 10, x_2**3 - 25*x_3   24], dtype='float32')    def f(x):  f_n = []  for i in range(len(x)):  f_i = f_bold[i]**2  f_n.append(f_i)    return sum(f_n)    def M(x):  x_1 = x[0]  x_2 = x[1]  d1 = 2*x_1  d2 = 2*x_2  d3 = 3*x_2**2  return array([[15, d1, 0], [d2, 10, d3], [-4, -1, -25]], dtype='float32')    def grad_f(x):  return 2*np.dot(M(x), f_bold(x))    def d(x):  return -1*grad_f(x)/norm(grad_f(x), ord=2)    def s_prime(x, alpha, d):  return np.dot(transpose(grad_f(x   alpha*d)), d)    x = array([[0.5], [0.5], [0.5]], dtype='float32')  iter = 0  err = 100   while err gt; 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) gt; 0.0005:  alpha = (alpha_l alpha_u)/2  sprime = s_prime(x_k, alpha, d_k)    if abs(sprime) lt; 0.001:  break  elif sprime gt; 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'nf_bold:nEquation 1 = {f_bold(x)[0][0]}nEquation 2 = {f_bold(x)[1][0]}nEquation 3 = {f_bold(x)[2][0]}n')  sdm_3eqs()