I am trying to use the symbolic libraries of the python Symp. I am getting lots of errors. How to overcome this. every time I don't want to type sym.symobls for defining some thing new.
from sympy import *
from math import *
W1, W2, W3,z1, z2, b, a,g,l = symbols('W1 W2 W3 z1 z2 b a g l')
l = b**2(g/sqrt(a));
#Beam Functions
W1 = simplify(c1*cos(b*x) + c2*sin(b*x) + c3*cosh(b*x) + c4*sinh(b*x));
The expression l = b**2(g/sqrt(a)) isn't valid. You need e.g. a * between the 2 and the opening bracket. Also note that after the assignment, l isn't a symbol anymore, but a symbolic expression.
You can avoid declaring many variables by using sympify(). That function gets a string as input and creates symbolic variables on the fly. With sympify a lot of standard functions also get their correct symbolic version.
As mentioned in the comments, from sympy import * can be problematic, especially if you also work with other libraries. For convenience, a lot of examples in the docs do use import *, but only for short programs which don't use other libraries.
Here is a simple standalone example which assigns a symbolic expression to l and shows the internal representation (note that the expression is placed into quotes):
from sympy import sympify, srepr
l = sympify("b**2*(g/sqrt(a))")
print(srepr(l))
W1 = sympify("simplify(c1*cos(b*x) + c2*sin(b*x) + c3*cosh(b*x) + c4*sinh(b*x))")
print(srepr(W1))
Output:
Mul(Pow(Symbol('a'), Rational(-1, 2)), Pow(Symbol('b'), Integer(2)), Symbol('g'))
Add(Mul(Symbol('c1'), cos(Mul(Symbol('b'), Symbol('x')))), Mul(Symbol('c2'), sin(Mul(Symbol('b'), Symbol('x')))), Mul(Symbol('c3'), cosh(Mul(Symbol('b'), Symbol('x')))), Mul(Symbol('c4'), sinh(Mul(Symbol('b'), Symbol('x')))))
Often, routines will allow string input so you can just refer to variables created automatically through sympifying an expression with a string:
>>> from sympy import S
>>> S('x')
x
>>> _.subs('x',42)
42
>>> S('2*x').coeff('x')
2
If all you are doing is working with single letter symbols and SymPy functions (and no other libraries) you can (and this is how I always start my sessions):
>>> from sympy.abc import *
>>> from sympy import *
I put the second import there so I get S as the shortcut to sympify rather than as symbol S.
I have a .py file with a function that calculates the gradient of a function at a point and returns the value of that gradient at the point. The function takes a np.array([2,]) as input and outputs another np.array([2,]). I am confused as to how I can call the function from the cmd line and run the function with a specified input.
Here is a code snippet:
import numpy as np
def grad(x):
x_1 = x[0]
x_2 = x[1]
df_dx_1 = 6*x
df_dx_2 = 8*x_2
df_dx = np.array([df_dx_1, df_dx_2])
return np.transpose(df_dx)
I would really appreciate your help!
EDIT: This question differs from the popular command line thread because I have a specific issue of not being able to recognise the numpy input
First change script to (Here it uses if __name__='__main__' to check if it is running from script, then import sys and pass first argument using sys.argv[0] to the function):
import numpy as np
def grad(x):
x_1 = x[0]
x_2 = x[1]
df_dx_1 = 6*x
df_dx_2 = 8*x_2
df_dx = np.array([df_dx_1, df_dx_2])
return np.transpose(df_dx)
if __name__ == '__main__':
import sys
grad(sys.argv[1])
And call it like:
python "YOURSCRIPTPATH.py" argument_1
You can have more than one command line argument:
import sys
import numpy as np
def grad(x):
# your grad function here
arr = np.array([int(sys.argv[1]), int(sys.argv[2])])
print(grad(arr))
Usage:
python gradient.py 10 5
You could just something like this in the command line:
$ python -c 'from YOURFILE import grad; print(grad(your_argument))'
I am trying to separately compute the elements of a Taylor expansion and did not obtain the results I was supposed to. The function to approximate is x**321, and the first three elements of that Taylor expansion around x=1 should be:
1 + 321(x-1) + 51360(x-1)**2
For some reason, the code associated with the second term is not working.
See my code below.
import sympy as sy
import numpy as np
import math
import matplotlib.pyplot as plt
x = sy.Symbol('x')
f = x**321
x0 = 1
func0 = f.diff(x,0).subs(x,x0)*((x-x0)**0/factorial(0))
print(func0)
func1 = f.diff(x,1).subs(x,x0)*((x-x0)**1/factorial(1))
print(func1)
func2 = f.diff(x,2).subs(x,x0)*((x-x0)**2/factorial(2))
print(func2)
The prints I obtain running this code are
1
321x - 321
51360*(x - 1)**2
I also used .evalf and .lambdify but the results were the same. I can't understand where the error is coming from.
f = x**321
x = sy.Symbol('x')
def fprime(x):
return sy.diff(f,x)
DerivativeOfF = sy.lambdify((x),fprime(x),"numpy")
print(DerivativeOfF(1)*((x-x0)**1/factorial(1)))
321*x - 321
I'm obviously just starting with the language, so thank you for your help.
I found a beginners guide how to Taylor expand in python. Check it out perhaps all your questions are answered there:
http://firsttimeprogrammer.blogspot.com/2015/03/taylor-series-with-python-and-sympy.html
I tested your code and it works fine. like Bazingaa pointed out in the comments it is just an issue how python saves functions internally. One could argument that for a computer it takes less RAM to save 321*x - 321 instead of 321*(x - 1)**1.
In your first output line it also gives you 1 instead of (x - 1)**0
As far as I checked, the indentation is correct, no brackets are missing and I have only imported packages in the previous lines But I still get invalid syntax error.
#!/usr/bin/python
import bpy
import mathutils
import numpy as np
from math import radians
from mathutils import Vector
from math import radians
from mathutils import Matrix
from bpy import context
def transform_mesh('parent', 'obj_to_be_transformed', (translate_x, translate_y, translate_z), (rot_x,rot_y,rot_z)):
obj= bpy.data.objects[parent]
obj1= bpy.data.objects[obj_to_be_transformed]
initial_mat = obj1.matrix_world
...some code
(x,y,z) = (translate_x, translate_y, translate_z)
orig_loc_mat = Matrix.Translation(orig_loc+ mathutils.Vector((x,y,z)))
...some more code
eul = mathutils.Euler((radians(rot_x), radians(rot_y), radians(rot_z)), 'XYZ')
rot_mat = eul.to_matrix().to_4x4()
obj.matrix_world = orig_loc_mat * rot_mat * orig_rot_mat * orig_scale_mat
bpy.context.scene.update()
return [initial_loc,initial_rot,initial_scale,loc,rot,scale]
transform_result= transform_mesh('Armature','Coil',(5,0,0),(0,0,1))
print (transform_result)
And error is:
Error: File "D:\users\gayathri\Gayathri\Synthetic_data_generation\Final\HMI_Depth_coilA_final_final.blend\Untitled", line 18
def transform_mesh('parent', 'obj_to_be_transformed', (translate_x, translate_y, translate_z), (rot_x,rot_y,rot_z)):
^
SyntaxError: invalid syntax
location: <unknown location>:-1
def transform_mesh('parent', 'obj_to_be_transformed',
should be
def transform_mesh(parent, obj_to_be_transformed,
surely?
1- Remove strings from arguments
2- Remove tuples from arguments and attribute them in the function (It might be useful to add some checks)
So, here you are:
def transform_mesh(parent, obj_to_be_transformed, translate, rot):
translate_x, translate_y, translate_z= translate
rot_x,rot_y,rot_z = rot
# etc
transform_result= transform_mesh('Armature','Coil',(5,0,0),(0,0,1))
print (transform_result)
Tuple parameters are not supported in Python3, but you can pass it as a variable and unpack it after defining the function.
def transform_mesh(translate_xyz):
translate_x, translate_y, translate_z = translate_xyz
You need to provide variables as arguments to the function.
try something like:
def transform_mesh(parent, obj_to_be_transformed, t1, t2):
Although in the code you have shared, you are always using t1 and t2 as tuples. But in case you want to use x, y and z separately, you can do it by referencing the index:
x = t1[0]
y = t1[1]
In this line the function parameter are passed in incorrect way,
def transform_mesh('parent', 'obj_to_be_transformed', (translate_x, translate_y, translate_z), (rot_x,rot_y,rot_z)):
The Correct syntax would be:
def transform_mesh(parent, obj_to_be_transformed, *translate_xyz, *rot_xyz): #*translate_xyz and *rot-xyz are tuple parameter
I wrote a function in Python 2.7:
# Python #
def function_py(par):
#something happens
return(value)
and I want to use this function as an argument for another function in R. More precisely, I want to perform to compute the Sobol' indices using the following function:
# R #
library('sensitivity')
sobol(function_py_translated, X1,X2)
where function_py_translated would b the R equivalent of function_py.
I'm trying to use the rpy2 module, and for a simple function, I could make a working case:
import rpy2.rinterface as ri
import rpy2.robjects.numpy2ri
sensitivity = importr('sensitivity')
radd = ri.baseenv.get('+')
def costfun(X):
a = X[0]
b = X[1]
return(radd(a,b))
costfunr=ri.rternalize(costfun)
X1 = robjects.r('data.frame(matrix(rnorm(2*1000), nrow = 1000))')
X2 = robjects.r('data.frame(matrix(rnorm(2*1000), nrow = 1000))')
sobinde = sensitivity.sobol(costfunr,X1,X2)
print(sobinde.__getitem__(11))
The main problem is that I had to redefine the "+". Is there a way to work around this ? Being able to pass an arbitrary function without prior transformation ? The function I want to analyze is much more complicated.
Thank you very much for your time