I have problems lambdifying a symbolic function that needs array arguments.
The problem I want to solve is to find the statistics of the product of
Normal distributions. Attached is an example that works and even yields the
correct answers. However, I think that the part where the symbolic versions
are lambdified into Python callable functions can't win a beauty contest.
For example a part of the class :
self.MeanNN = E(NN)
self.meanNN = lambdify([mu, s], self.MeanNN)
def meanOfNs(self, mu, s):
mus = mu + s
return self.meanNN(*mus)
Than called as:
Nn = ProductOfNormals(n)
print('Mean: ', Nn.meanOfNs(mu, s))
Where mu and s are lists of length n
In case the arguments are spelled out it looks nicer but I want the
flexibility of variable number of distributions in the product.
e.g.:
self.MeanNN = E(NN)
self.meanNN = lambdify([mu1, s1, mu2, s2], self.MeanNN)
Than:
NN = ProductNormalNormal()
print('Mean: ', NN.meanNN(mu0, s0, mu1, s1))
Where all parms are scalar
Any tips on how to get a more elegant solution are welcome!!
The complete example is attached. I am using SymPy 0.7.3 on Python 2.7.4 on
Linux.
Cheers, Janwillem
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sympy.
For more options, visit https://groups.google.com/groups/opt_out.
# -*- coding: utf-8 -*-
"""
Created on Wed Aug 28 13:33:03 2013
@author: Janwillem van Dijk
Statistics of the product of two or more normal (Gaussian) distributions
with non-zero means.
"""
from __future__ import print_function
from sympy import Symbol, symbols, lambdify
from sympy import sqrt as SQRT
from sympy.stats import Normal, E, variance, skewness
from math import sqrt
class ProductNormalNormal():
def __init__(self):
mu1 = Symbol('mu1', positive=True, real=True, bounded=True)
s1 = Symbol('s1', positive=True, real=True, bounded=True)
mu2 = Symbol('mu2', positive=True, real=True, bounded=True)
s2 = Symbol('s2', positive=True, real=True, bounded=True)
N1 = Normal('N1', mu1, s1)
N2 = Normal('N2', mu2, s2)
NN = N1 * N2
self.MeanNN = E(NN)
self.VarNN = variance(NN)
self.StdevNN = SQRT(self.VarNN)
self.SkewNN = skewness(NN)
self.meanNN = lambdify([mu1, s1, mu2, s2], self.MeanNN)
self.varNN = lambdify([mu1, s1, mu2, s2], self.VarNN)
self.stdevNN = lambdify([mu1, s1, mu2, s2], self.StdevNN)
self.skewNN = lambdify([mu1, s1, mu2, s2], self.SkewNN)
class ProductOfNormals():
def __init__(self, n):
mu = symbols('mu0:%d' % n, positive=True, real=True, bounded=True)
s = symbols('s0:%d' % n, positive=True, real=True, bounded=True)
N = []
for i in range(n):
N.append(Normal('N%d' % i, mu[i], s[i]))
NN = N[-1]
for i in range(n - 1):
NN *= N[i]
self.DistributionNN = NN
self.MeanNN = E(NN)
self.VarNN = variance(NN)
self.StdevNN = SQRT(self.VarNN)
self.SkewNN = skewness(NN)
self.meanNN = lambdify([mu, s], self.MeanNN)
self.varNN = lambdify([mu, s], self.VarNN)
self.stdevNN = lambdify([mu, s], self.StdevNN)
self.skewNN = lambdify([mu, s], self.SkewNN)
def meanOfNs(self, mu, s):
mus = mu + s
return self.meanNN(*mus)
def varOfNs(self, mu, s):
mus = mu + s
return self.varNN(*mus)
def stdevOfNs(self, mu, s):
mus = mu + s
return self.stdevNN(*mus)
def skewOfNs(self, mu, s):
mus = mu + s
return self.skewNN(*mus)
def densityOfNs(self, x, mu, s):
mus = mu + s
return self.densityNN(*mus)(x)
if __name__ == '__main__':
from sympy import pprint
n = 2
mu0 = 1.0
s0 = 0.05
mu1 = 1.0
s1 = 0.15
Nn = ProductOfNormals(n)
print('Sympy formula product of %d N(mu,s)', n)
print('Mean')
pprint(Nn.MeanNN)
print('\nVariance')
pprint(Nn.VarNN)
print('\nSkewness')
pprint(Nn.SkewNN)
s0n = s0 / sqrt(n - 1)
print('\ns0: ', s0)
print('s0n: ', s0n)
mu = [mu1]
s = [s1]
for i in range(n - 1):
mu.insert(0, mu0)
s.insert(0, s0)
print('\nMean: ', Nn.meanOfNs(mu, s))
print('Var: ', Nn.varOfNs(mu, s))
print('Stdev: ', Nn.stdevOfNs(mu, s))
print('Skew: ', Nn.skewOfNs(mu, s))
NN = ProductNormalNormal()
print('\nSympy formula NN(mu,s)*NN(mu,s)')
print('Mean')
pprint(Nn.MeanNN)
print('\nVariance')
pprint(Nn.VarNN)
print('\nSkewness')
pprint(Nn.SkewNN)
print('\nMean: ', NN.meanNN(mu0, s0, mu1, s1))
print('Var: ', NN.varNN(mu0, s0, mu1, s1))
print('Stdev: ', NN.stdevNN(mu0, s0, mu1, s1))
print('Skew: ', NN.skewNN(mu0, s0, mu1, s1))