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 sympy+unsubscr...@googlegroups.com. To post to this group, send email to sympy@googlegroups.com. 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))