Home > Mobile >  Can't convert expression to float - using sympy
Can't convert expression to float - using sympy

Time:10-25

I have this code below but I have ran into an error and am unsure what to do. I have tried changing the dtype on the arrays but that doesn't work either.

import sympy as sym
import numpy as np
from numpy.linalg import norm
from numpy import transpose
from numpy import array
from numpy import sum
from matplotlib import pyplot as plt

def equations():
    a, b, c = sym.symbols('x y z')

    f_xyz_1 = 15*a   b**2 - 4*c - 15
    f_xyz_2 = a**2   10*b - c - 10 
    f_xyz_3 = b**3 - 25*c   24

    return [f_xyz_1, f_xyz_2, f_xyz_3]

def f_bold(x):
    a, b, c = sym.symbols('x y z')
    vals = {a: x[0], b: x[1], c: x[2]}

    f_new_1 = equations()[0].subs(vals)
    f_new_2 = equations()[1].subs(vals)
    f_new_3 = equations()[2].subs(vals)    
    return array([[f_new_1], [f_new_2], [f_new_3]], dtype='float64')

def f(x):
    f_n = []
    for i in range(len(x)):
        f_i = f_bold(x)[i]**2
        f_n.append(f_i)

    return sum(f_n)

def M(x):
    a, b, c = sym.symbols('x y z')
    vals = {a: x[0], b: x[1], c: x[2]}

    f_xyz_1_diff_x = sym.diff(equations()[0], a).subs(vals)
    f_xyz_1_diff_y = sym.diff(equations()[0], b).subs(vals)
    f_xyz_1_diff_z = sym.diff(equations()[0], c).subs(vals)

    f_xyz_2_diff_x = sym.diff(equations()[1], a).subs(vals)
    f_xyz_2_diff_y = sym.diff(equations()[1], b).subs(vals)
    f_xyz_2_diff_z = sym.diff(equations()[1], c).subs(vals)

    f_xyz_3_diff_x = sym.diff(equations()[2], a).subs(vals)
    f_xyz_3_diff_y = sym.diff(equations()[2], b).subs(vals)
    f_xyz_3_diff_z = sym.diff(equations()[2], c).subs(vals)

    return array([[f_xyz_1_diff_x, f_xyz_2_diff_x, f_xyz_3_diff_x], [f_xyz_1_diff_y, f_xyz_2_diff_y, f_xyz_3_diff_y], [f_xyz_1_diff_z, f_xyz_2_diff_z, f_xyz_3_diff_z]], dtype='float64')

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)))

x = [0.5, 0.5, 0.5]
alpha = 0.75
print(s_prime(x, alpha, d(x)))

When I print s_prime, it prints the following traceback:

Traceback (most recent call last):
  File "/Users/aidanpayne/Desktop/Scripts/Python/University of Greenwich/MATH1157/Scripts/Steepest Descent Method for three equations.py", line 64, in <module>
    print(s_prime(x, alpha, d(x)))
  File "/Users/aidanpayne/Desktop/Scripts/Python/University of Greenwich/MATH1157/Scripts/Steepest Descent Method for three equations.py", line 60, in s_prime
    return np.dot(transpose(grad_f(x   alpha*d)))
  File "/Users/aidanpayne/Desktop/Scripts/Python/University of Greenwich/MATH1157/Scripts/Steepest Descent Method for three equations.py", line 54, in grad_f
    return 2*np.dot(M(x), f_bold(x))
  File "/Users/aidanpayne/Desktop/Scripts/Python/University of Greenwich/MATH1157/Scripts/Steepest Descent Method for three equations.py", line 51, in M
    return array([[f_xyz_1_diff_x, f_xyz_2_diff_x, f_xyz_3_diff_x], [f_xyz_1_diff_y, f_xyz_2_diff_y, f_xyz_3_diff_y], [f_xyz_1_diff_z, f_xyz_2_diff_z, f_xyz_3_diff_z]], dtype='float64')
  File "/Users/aidanpayne/opt/anaconda3/lib/python3.8/site-packages/sympy/core/expr.py", line 327, in __float__
    raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float

But when I print the other defs, it doesn't print any errors.

CodePudding user response:

The correct code:

import sympy as sym
import numpy as np
from numpy.linalg import norm
from numpy import transpose
from numpy import array
from numpy import sum
from matplotlib import pyplot as plt

def equations():
    a, b, c = sym.symbols('x y z')

    f_xyz_1 = 15*a   b**2 - 4*c - 15
    f_xyz_2 = a**2   10*b - c - 10 
    f_xyz_3 = b**3 - 25*c   24

    return [f_xyz_1, f_xyz_2, f_xyz_3]

def f_bold(x):
    a, b, c = sym.symbols('x y z')
    vals = {a: x[0][0], b: x[1][0], c: x[2][0]}

    f_new_1 = equations()[0].subs(vals)
    f_new_2 = equations()[1].subs(vals)
    f_new_3 = equations()[2].subs(vals)

    out_arr = [[f_new_1], [f_new_2], [f_new_3]]

    return array(out_arr, dtype='float32')

def f(x):
    f_n = []
    for i in range(len(x)):
        f_i = f_bold(x)[i]**2
        f_n.append(f_i)

    return sum(f_n)

def M(x):
    a, b, c = sym.symbols('x y z')
    vals = {a: x[0][0], b: x[1][0], c: x[2][0]}

    f_xyz_1_diff_x = sym.diff(equations()[0], a).subs(vals)
    f_xyz_1_diff_y = sym.diff(equations()[0], b).subs(vals)
    f_xyz_1_diff_z = sym.diff(equations()[0], c).subs(vals)

    f_xyz_2_diff_x = sym.diff(equations()[1], a).subs(vals)
    f_xyz_2_diff_y = sym.diff(equations()[1], b).subs(vals)
    f_xyz_2_diff_z = sym.diff(equations()[1], c).subs(vals)

    f_xyz_3_diff_x = sym.diff(equations()[2], a).subs(vals)
    f_xyz_3_diff_y = sym.diff(equations()[2], b).subs(vals)
    f_xyz_3_diff_z = sym.diff(equations()[2], c).subs(vals)

    out_arr = [[f_xyz_1_diff_x, f_xyz_2_diff_x, f_xyz_3_diff_x], [f_xyz_1_diff_y, f_xyz_2_diff_y, f_xyz_3_diff_y], [f_xyz_1_diff_z, f_xyz_2_diff_z, f_xyz_3_diff_z]]

    return array(out_arr, 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 = [0.5, 0.5, 0.5]
x = np.reshape(x, (3, 1))
alpha = 0.75
d_k = d(x)

print(s_prime(x, alpha, d_k))
  • Related