Reputation:
As a newcomer to Python world, I'm just simply about to linearize the following two variable function:
function
using the fairly routine Newton method:
linearization method
Here is what I've tried so far:
import numpy as np
import math
from sympy import symbols, diff
d = 1.7
def f(arg1, arg2):
return (arg1 - arg2)/(np.power(np.linalg.norm(arg1 - arg2),2) - np.power(d,2))
def linearize_f(f, arg1, arg2, equi_arg1, equi_arg2):
arg1, arg2 = symbols('arg1 arg2', real=True)
der_1 = diff(f(arg1,arg2), arg1)
der_2 = diff(f(arg1,arg2), arg2)
constant_term = f(equi_arg1, equi_arg2)
vars = sympy.symbols('arg1, arg2')
par_term_1 = sympy.evalf(der_1, subs = dict(zip(vars,[equi_arg1, equi_arg2])))
par_term_2 = sympy.evalf(der_2, subs = dict(zip(vars,[equi_arg1, equi_arg2])))
result = constant_term + par_term_1*(arg1-equi_arg1) + par_term_2*(arg2-equi_arg2)
return result
q0, q1 = symbols('q0 q1', real=True)
result = linearize_f(f,q0,q1,0,0)
print(result)
The interpreter returns a 'Pow' object has no attribute 'sqrt'
. However, I've never used any sqrt
in my code.
Would you please help me to resolve the case?
Upvotes: 7
Views: 1418
Reputation: 5958
I've narrowed your error to this:
q0, q1 = symbols('q0 q1', real=True)
np.linalg.norm(q0 - q1) # Throws the same error
Here's the source code in np.linalg
where it threw the error:
2347
2348 # Immediately handle some default, simple, fast, and common cases.
2349 if axis is None:
2350 ndim = x.ndim
2351 if ((ord is None) or
2352 (ord in ('f', 'fro') and ndim == 2) or
2353 (ord == 2 and ndim == 1)):
2354
2355 x = x.ravel(order='K')
2356 if isComplexType(x.dtype.type):
2357 sqnorm = dot(x.real, x.real) + dot(x.imag, x.imag)
2358 else:
2359 sqnorm = dot(x, x)
2360 ret = sqrt(sqnorm)
2361 if keepdims:
2362 ret = ret.reshape(ndim*[1])
2363 return ret
Apparently, after your sympy object has been processed by dot
, it became a Pow
object, which is a sympy object that np.sqrt
has no idea what to do with.
The reason for this apparently is that you cannot use numpy
function for sympy
objects. Pow
is a sympy object and as such numpy.sqrt
cannot operate on this object.
After more reasearch, apparently this question from long time ago sympy AttributeError: 'Pow' object has no attribute 'sin' also point to the same reason.
Upvotes: 2
Reputation: 29081
You have not called sqrt
but np.linalg.norm
has. The arg1, arg2
arguments are of type sympy.Symbol
. The function expects to get an array-like argument. However, it gets a sympy symbol, which it does not know how to handle.
I looked in the np.linalg
source code, and it seems that it checks for some known types and tries to find the square root. Otherwise, it relies on the argument itself to know its own square root. sympy.Symbol
has no such thing, and hence the error.
There is no way to avoid this. numpy works with numbers, sympy works with (its own) symbols. You are not supposed to mix them. Most likely sympy will have its own functions for handling its own symbols, but, if not, you are out of luck, unless you add them yourself.
Upvotes: 3