Code for this expression in python - python

I'm trying to code this expression in python but I'm having some difficulty.
This is the code I have so far and wanted some advice.
x = 1x2 vector
mu = 1x2 vector
Sigma = 2x2 matrix
xT = (x-mu).transpose()
sig = Sigma**(-1)
dotP = dot(xT ,sig )
dotdot = dot(dotP, (x-mu))
E = exp( (-1/2) dotdot )
Am I on the right track? Any suggestions?

Sigma ** (-1) isn't what you want. That would raise each element of Sigma to the -1 power, i.e. 1 / Sigma, whereas in the mathematical expression it means the inverse, which is written in Python as np.linalg.inv(Sigma).
(-1/2) dotdot is a syntax error; in Python, you need to always include * for multiplication, or just do - dotdot / 2. Since you're probably using python 2, division is a little wonky; unless you've done from __future__ import division (highly recommended), 1/2 will actually be 0, because it's integer division. You can use .5 to get around that, though like I said I do highly recommend doing the division import.
This is pretty trivial, but you're doing the x-mu subtraction twice where it's only necessary to do once. Could save a little speed if your vectors are big by doing it only once. (Of course, here you're doing it in two dimensions, so this doesn't matter at all.)
Rather than calling the_array.transpose() (which is fine), it's often nicer to use the_array.T, which is the same thing.
I also wouldn't use the name xT; it implies to me that it's the transpose of x, which is false.
I would probably combine it like this:
# near the top of the file
# you probably did some kind of `from somewhere import *`.
# most people like to only import specific names and/or do imports like this,
# to make it clear where your functions are coming from.
import numpy as np
centered = x - mu
prec = np.linalg.inv(Sigma)
E = np.exp(-.5 * np.dot(centered.T, np.dot(prec, centered)))

Related

Sympy cannot evaluate an infinite sum involving gamma functions

I am using Sympy to evaluate some symbolic sums that involve manipulations of the gamma functions but I noticed that in this case it's not evaluating the sum and keeps it unevaluated.
import sympy as sp
a = sp.Symbol('a',real=True)
b = sp.Symbol('b',real=True)
d = sp.Symbol('d',real=True)
c = sp.Symbol('c',integer=True)
z = sp.Symbol('z',complex=True)
t = sp.Symbol('t',complex=True)
sp.simplify(t-sp.summation((sp.exp(-d)*(d**c)/sp.gamma(c+1))/(z-c-a*t),(c,0,sp.oo)))
I then need to lambdify this expression, and unfortunately this becomes impossible to do.
With Matlab symbolic toolbox however I get the following answer:
Matlab
>> a=sym('a')
>> b=sym('b');
>> c=sym('c')
>> d=sym('d');
>> z=sym('z');
>> t=sym('t');
>> symsum((exp(-d)*(d^c)/factorial(c))/(z-c-a*t),c,0,inf)
ans =
(-d)^(z - a*t)*exp(-d)*(gamma(a*t - z) - igamma(a*t - z, -d))
The formula involves lower incomplete gamma functions, as expected.
Any idea why of this behaviour? I thought sympy was able to do this summation symbolically.
Running your code with SymPy 1.2 results in
d**(-a*t + z)*exp(-I*pi*a*t - d + I*pi*z)*lowergamma(a*t - z, d*exp_polar(I*pi)) + t
By the way, summation already attempts to evaluate the sum (and succeeds in case of SymPy 1.2), subsequent simplification is cosmetic. (And can sometimes be harmful).
The presence of exp_polar means that SymPy found it necessary to consider the points on the Riemann surface of logarithmic function instead of regular complex numbers. (Related bit of docs). The function lower_gamma is branched and so we must distinguish between "the value at -1, if we arrive to -1 from 1 going clockwise" from "the value at -1, if we arrive to -1 from 1 going counterclockwise". The former is exp_polar(-I*pi), the latter is exp_polar(I*pi).
All this is very interesting but not really helpful when you need concrete evaluation of the expression. We have to unpolarify this expression, and from what Matlab shows, simply replacing exp_polar with exp is a correct way to do so here.
rv = sp.simplify(t-sp.summation((sp.exp(-d)*(d**c)/sp.gamma(c+1))/(z-c-a*t),(c,0,sp.oo)))
rv = rv.subs(sp.exp_polar, sp.exp)
Result: d**(-a*t + z)*exp(-I*pi*a*t - d + I*pi*z)*lowergamma(a*t - z, -d) + t
There is still something to think about here, with complex numbers and so on. Is d positive or negative? What does raising it to the power -a*t+z mean, what branch of multivalued power function do we take? The same issues are present in Matlab output, where -d is raised to a power.
I recommend testing this with floating point input (direct summation of series vs evaluation of the SymPy expression for it), and adding assumptions on the sign of d if possible.

Python-How to do Algebraic Math with Exponents and Square Roots

so I am having issues trying to do basic math in Python. I can do basic math, but when I add in exponents, square roots, etc, I have errors with the IDE. How do I do this?
Here are a few of my problems that I am having issues with:
(n(n-1))/2)
(4)* pi * r ** 2=
(r(cos(a)**2) + r(sin(b))**2)**(.5)
((y**2) - (y**1))/((x**2) - (x**1))=
(n*(n-1))/2 should work if you have already given n a numeric value (e.g. n=2 or something). Your original expression has unbalanced parentheses (three closing parens and only two opening parens) and it is missing the multiplication sign (*) which is necessary in python, otherwise n(n-1) would be interpreted as the function n supplied with the input n-1, in which case you get a message like "TypeError: 'int' object is not callable", assuming you had previously defined n=2 or the like. It's telling you that the integer n cannot be called like a function, which is how it interprets n().
To get pi (3.14159...) in python, you should import the math package and then use math.pi like this:
import math
r = 2
x = 4*math.pi*r**2
You don't need parentheses around the 4. Parentheses are used for grouping, when you need operations to be done in a different order than the standard order of operations. You don't need the trailing equal sign (that's a syntax error).
In the third expression you are using implicit multiplication notation which is fine for pencil and paper but in python you need to use * every time you multiply. Also, you need to import the math package and then use math.sin and math.cos.
import math
a = 90
b = 45
x = (r*(math.cos(a)**2) + r*(math.sin(b))**2)**(.5)
There doesn't appear to be anything wrong with the last expression except the trailing = sign which should be removed. Store the result of this expression in a variable if you want to keep it for future use:
z = ((y**2) - (y**1))/((x**2) - (x**1))
If you just type the expression at the command line it will print the result immediately:
x = 3
y = 2
((y**2) - (y**1))/((x**2) - (x**1))
but if you are using this expression in a script you want to save the result in a variable so you can use it later or print it out or something:
z = ((y**2) - (y**1))/((x**2) - (x**1))
As was previously pointed out in the comments, x**1 is the same, mathematically, as x so it's not clear why you would want to write it this way, but it's not wrong.
You can use math.pow() or the simpler ** syntax:
There are two ways to complete basic maths equations in python either:
use the ** syntax. e.g:
>>> 2 ** 4
16
>>> 3 ** 3
27
or use math.pow(). e.g:
>>> import math
>>> math.pow(5, 2)
25.0
>>> math.pow(36, 0.5)
6.0
As you can see, with both of these functions you can use any real power so negative for inverse or decimals for roots.
In general, for these types of equations, you want to look into the math module. It has lost of useful functions and defined constants that you may find useful. In particular for your specific problems: math.pi and these trig. functions.
I hope these examples and the links I made are useful for you :)

Python plot of force in Lennard-Jones system gives TypeError

I am trying to plot the force on the ith particle as function of its distance from the jth particle (ie. xi-xj) in a Lennard-Jones system. The force is given by
where sigma and epsilon are two parameters, Xi is a known quantity and Xj is variable. The force directs from the ith particle to the jth particle.
The code that I have written for this is given below.
from pylab import*
from numpy import*
#~~~ ARGON VALUES ~~~~~~~~(in natural units)~~~~~~~~~~~~~~~~
epsilon=0.0122 # depth of potential well
sigma=0.335 # dist of closest approach
xi=0.00
xj=linspace(0.1,1.0,300)
f = 48.0*epsilon*( ((sigma**12.0)/((xi-xj)**13.0)) - ((sigma**6.0)/2.0/((xi-xj)**7.0)) ) * float(xj-xi)/abs(xi-xj)
plot(xj,f,label='force')
legend()
show()
But it gives me this following error.
f = 48.0*epsilon*( ((sigma**12.0)/((xi-xj)**11.0)) - ((sigma**6.0)/2.0/((xi-xj)**5.0)) ) * float(xj-xi)/abs(xi-xj)
TypeError: only length-1 arrays can be converted to Python scalars
Can someone help me solve this problem. Thanks in advance.
The error is with this part of the expression:
float(xj-xi)
Look at the answer to a related question. It appears to be conflict between Python built-in functions and Numpy functions.
If you take out the 'float' it at least returns. Does it give the correct numbers?
f = 48.0*epsilon*( ((sigma**12.0)/((xi-xj)**11.0)) - ((sigma**6.0)/2.0/((xi-xj)**5.0)) ) * (xj-xi)/abs(xi-xj)
Instead of the term float(xj-xi)/abs(xi-xj) you should use
sign(xj-xi)
If you really want to do the division, since xi and xj are already floats you could just do:
(xj-xi)/abs(xi-xj)
More generally, if you need to convert a numpy array of ints to floats you could use either of:
1.0*(xj-xi)
(xj-xi).astype(float)
Even more generally, it's helpful in debugging to not use equations that stretch across the page because with smaller terms you can identify the location of the errors more easily. It also often runs faster. For example, here you calculate xi-xj four times, when really it only needs to be done once. And it would be easier to read:
x = xi -xj
f = 48*epsilon*(s**12/x**13 - s**6/2/x**7)
f *= sign(-x)
The TypeError is due to float(xi-xj). float() cannot convert an iterable to a single scalar value. Instead, iterate over xj and convert each value in xi-xj to float. This can be easily done with
x = [float(j - xi) for j in xj)]

Associated Legendre Function

Hi I am writing Python code which returns the associated Legendre function.
Using numpy poly1d function on this part,
firstTerm = (np.poly1d([-1,0,1]))**(m/2.0) # HELP!
It yields an error since it can only be raised to integer.
Is there any other alternative where I can raise the desired function to power 1/2 and etc.?
The reason you can't raise your poly1d to half-integer power is that that would not be a polynomial, since it would contain square roots.
While in principle you could orthogonalize the functions yourself, or construct the functions from something like sympy.special.legendre, but your safest bet is symbolic math. And hey, we already have sympy.functions.special.polynomials.assoc_legendre! Since symbolic math is slow, you should probably use sympy.lambdify to turn each function into a numerical one:
import sympy as sym
x = sym.symbols('x')
n = 3
m = 1
legfun_sym = sym.functions.special.polynomials.assoc_legendre(n,m,x)
legfun_num = sym.lambdify(x,legfun_sym)
print(legfun_sym)
print(legfun_num)
x0 = 0.25
print(legfun_sym.evalf(subs={x:x0}) - legfun_num(x0))
This prints
-sqrt(-x**2 + 1)*(15*x**2/2 - 3/2)
<function <lambda> at 0x7f0a091976e0>
-1.11022302462516e-16
which seems to make sense (the first is the symbolic function at x, the second shows that lambdify indeed creates a lambda from the function, and the last one is the numerical difference of the two functions at the pseudorandom point x0 = 0.25, and is clearly zero within machine precision).

Model measurement and error in NumPy

I'd like to try the SciPy suite instead of Octave for doing the statistics in my lab experiments. Most of my questions were answered here, there is just another thing left:
I usually have an error attached to the measurements, in Octave I just did the following:
R.val = 10;
R.err = 0.1;
U.val = 4;
U.err = 0.1;
And then I would calculate I with it like so:
I.val = U.val / R.val;
I.err = sqrt(
(1 / R.val * U.err)^2
+ (U.val / R.val^2 * R.err)^2
);
When I had a bunch of measurements, I usually used a structure array, like this:
R(0).val = 1;
R(0).err = 0.1;
…
R(15).val = 100;
R(15).err = 9;
Then I could do R(0).val or directly access all of them using R.val and I had a column vector with all the values, for mean(R.val) for instance.
How could I represent this using SciPy/NumPy/Python?
This kind of error propagation is exactly what the uncertainties Python package does. It does so transparently and by correctly handling correlations:
from uncertainties import ufloat
R = ufloat(10, 0.1)
U = ufloat(4, 0.1)
I = U/R
print I
prints 0.4+/-0.0107703296143, after automatically determining and calculating the error formula that you typed manually in your example. Also, I.n and I.s are respectively the nominal value (your val) and the standard deviation (your err).
Arrays holding numbers with uncertainties can also be used (http://pythonhosted.org/uncertainties/numpy_guide.html).
(Disclaimer: I'm the author of this package.)
The easiest is indeed to use NumPy structured arrays, that give you the possibility to define arrays of homogeneous elements (a record) composed of other homogeneous elements (fields).
For example, you could define
R = np.empty(15, dtype=[('val',float),('err',float)])
and then fill the corresponding columns:
R['val'] = ...
R['err'] = ...
Alternatively, you could define the array at once if you have your val and err in two lists:
R = np.array(zip(val_list, err_list), dtype=[('val',float),('err',float)])
In both cases, you can access individual elements by indices, like R[0] (which would give you a specific object, a np.void, that still gives you the possibility to access the fields separately), or by slices R[1:-1]...
With your example, you could do:
I = np.empty_like(R)
I['val'] = U['val'] / R['val']
I['err'] = np.sqrt((1 / R['val'] * U['err'])**2 + (U['val'] / R['val']**2 * R['err'])**2)
You could also use record array, which are basic structured array with the __getattr__ and __setattr__ methods overloaded in such way that you can access the fields as attributes (like in R.val) as well as indices (like the standard R['val']). Of course, as these basic methods are overloaded, record arrays are not as efficient as structured arrays.
For just one measurement probably simple namedtuple would suffice.
And instead of structure arrays you can use numpy's record arrays. Seems to be little bit more mouthful though.
Also google cache of NumPy for Matlab Users (direct link doesn't work for me atm) can help with some counterparts of basic operations.
There is a package for representing quantities along with uncertainties in Python. It is called quantities ! (also on PyPI).

Categories