Sympify of factorials in Sympy - sympy

I have the following Sympy code that works as expected:
import numpy as np
from sympy.utilities.lambdify import lambdify
from sympy.core import sympify
from sympy import factorial
ex = sympify('-x**2 / cos(x)')
flam = lambdify(['x'], ex, "numpy")
flam(np.array(range(5)))
This returns:
array([ 0. , -1.85081572, 9.61199185, 9.09097799, 24.4781705 ])
Now, what I need to know is how to do the same for factorials, that is, using factorial(x) instead of cos(x). The code:
ex = sympify('-x**2 / factorial(x)')
flam = lambdify(['x'], ex, "numpy")
flam(np.array(range(5)))
raises a NameError
NameError: global name 'factorial' is not defined
What string should I use so that it gets converted to a factorial that can be evaluated after lambdify?
Thanks in advance for any help!

By tinkering I obtain the following code. It seems that the numpy factorial function do not works with ndarrays...
import numpy as np
from sympy.utilities.lambdify import lambdify
flam = lambdify(['x'], '-x**2 / cos(x)', "numpy")
flam(np.array(range(5)))
# >>> array([ 0. , -1.85081572, 9.61199185, 9.09097799, 24.4781705 ])
import scipy.special
flam = lambdify('x', 'factorial(x)', ['numpy', {'factorial':scipy.special.factorial}])
flam(np.array(range(5)))
# >>> array([ 1., 1., 2., 6., 24.])

Related

How to fix "TypeError: only length-1 arrays can be converted to Python scalars" in python regression

I tried to use scipy.optimize package for regression. The model of the function is defined in func with parameters named as coeffs. I want to use the data xdata and ydata to learn the parameters using LS criterion.
I have the following TypeError: only length-1 arrays can be converted to Python scalars
from __future__ import division
import numpy
import scipy
from math import exp
import scipy.optimize as optimization
global m0,t0
t0 = 0.25
m0=1
def func(t, coeffs):
a = coeffs[0]
b = coeffs[1]
m = (a/b + m0 )*exp(b*(t-t0))-a/b
return m
# fitting test
x0 = numpy.array([5, -5], dtype=float)
def residuals(coeffs, y, t):
return y - func(t, coeffs)
xdata = numpy.array([0.25,0.5,1])
ydata = numpy.array([1.0,0.803265329856,0.611565080074])
from scipy.optimize import leastsq
x = leastsq(residuals, x0, args=(ydata, xdata))
return parameters are expected around [2,-1].
Do not use from math import exp, replace it by from numpy import exp so that your arrays are correctly handled: the numpy.exp function will return the array expected by scipy, with each element converted to its exponential value.

Error: __init__() got an unexpected keyword argument 'n_splits'

I am going to perform ShuffleSplit() method for California housing dataset (Source: https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html) to fit SGD regression.
However, the 'n_splits' error is occurred when method is applied.
The code is following:
from sklearn import cross_validation, grid_search, linear_model, metrics
import numpy as np
import pandas as pd
from sklearn.preprocessing import scale
from sklearn.cross_validation import ShuffleSplit
housing_data = pd.read_csv('cal_housing.csv', header = 0, sep = ',')
housing_data.fillna(housing_data.mean(), inplace=True)
df=pd.get_dummies(housing_data)
y_target = housing_data['median_house_value'].values
x_features = housing_data.drop(['median_house_value'], axis = 1)
from sklearn.cross_validation import train_test_split
from sklearn import model_selection
train_x, test_x, train_y, test_y = model_selection.train_test_split(x_features, y_target, test_size=0.2, random_state=4)
reg = linear_model.SGDRegressor(random_state=0)
cv = ShuffleSplit(n_splits = 10, test_size = 0.2, random_state = 0)
The error is below:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-22-8f8760b04f8c> in <module>()
----> 1 cv = ShuffleSplit(n_splits = 10, test_size = 0.2, random_state = 0)
TypeError: __init__() got an unexpected keyword argument 'n_splits'
I updated scikit-learn with 0.18 version.
Anaconda version: 4.5.8
Could you please advise on this issue?
You are mixing up two different modules.
Before 0.18, cross_validation was used for ShuffleSplit. In that, n_splits was not present. n was used to define the number of splits
But since you have updated to 0.18 now, cross_validation and grid_search has been deprecated in favor of model_selection.
This is mentioned in docs here, and these modules will be removed from version 0.20
So instead of this:
from sklearn.cross_validation import ShuffleSplit
from sklearn.cross_validation import train_test_split
Do this:
from sklearn.model_selection import ShuffleSplit
fro
m sklearn.model_selection import train_test_split
Then you can use n_splits.
cv = ShuffleSplit(n_splits = 10, test_size = 0.2, random_state = 0)

Custom multivariate Dirichlet priors in pymc3

Is it possible create custom multivariate distributions in pymc3? In the following, I have tried to create a linear transformation of a Dirichlet distribution. All variants on this have returned numerous errors, perhaps to do with theano data types? Any help would be gratefully appreciated.
import numpy as np
import pymc3 as pymc
import theano.tensor as tt
# data
n = 5
prior_params = np.ones(n - 1) / (n - 1)
mx = np.array([[0.25 , 0.5 , 0.75 , 1. ],
[0.25 , 0.333, 0.25 , 0. ],
[0.25 , 0.167, 0. , 0. ],
[0.25 , 0. , 0. , 0. ]])
# Note that the matrix mx takes the unit simplex into the unit simplex.
# custom log-liklihood
def generate_function(mx, prior_params):
def log_trunc_dir(x):
return pymc.Dirichlet.dist(a=prior_params).logp(mx.dot(x.T)).eval()
return log_trunc_dir
#model
with pymc.Model() as simple_model:
x = pymc.Dirichlet('x', a=np.ones(n - 1))
q = pymc.DensityDist('q', generate_function(mx, prior_params), observed={'x': x})
Thanks to significant help from the PyMC3 development community, I can post the
following working example of a customised Dirichlet prior in PyMC3.
import pymc3 as pm
import numpy as np
import scipy.special as special
import theano.tensor as tt
import matplotlib.pyplot as plt
n = 4
with pm.Model() as model:
prior = np.ones(n) / n
def dirich_logpdf(value=prior):
return -n * special.gammaln(1/n) + (-1 + 1/n) * tt.log(value).sum()
stick = pm.distributions.transforms.StickBreaking()
probs = pm.DensityDist('probs', dirich_logpdf, shape=n,
testval=np.array(prior), transform=stick)
data = np.array([5, 7, 1, 0])
sfs_obs = pm.Multinomial('sfs_obs', n=np.sum(data), p=probs, observed=data)
with model:
step = pm.Metropolis()
trace = pm.sample(100000, tune=10000, step=step)
print('MLE = ', data / np.sum(data))
print(pm.summary(trace))
pm.traceplot(trace, [probs])
plt.show()

Understanding of a logistic regression example

I am new to Logistic regression. The following is from package mypc example
project. It is still unclear to me for its purpose. More specifically,
variable n is [5, 5, 5, 5], which is used in the mode: pymc.Binomial.
I suppose it should have both 0 and 1 in binomial fitting. n is to represent
'1' cases?
Could you explain the idea of this example? Thanks,
The example is from:
www.map.ox.ac.uk/media/PDF/Patil_et_al_2010.pdf
.........
import pymc
import numpy as np
n = 5*np.ones(4,dtype=int)
x = np.array([-.86,-.3,-.05,.73])
alpha = pymc.Normal('alpha',mu=0,tau=.01)
beta = pymc.Normal('beta',mu=0,tau=.01)
#pymc.deterministic
def theta(a=alpha, b=beta):
"""theta = logit^{-1}(a+b)"""
return pymc.invlogit(a+b*x)
d = pymc.Binomial('d', n=n, p=theta, value=np.array([0.,1.,3.,5.]),\
observed=True)
.......
import pymc
import pymc.Matplot
import mymodel
S = pymc.MCMC(mymodel, db='pickle')
S.sample(iter=10000, burn=5000, thin=2)
pymc.Matplot.plot(S)
import matplotlib.pyplot as plt
plt.show()

Python how to plot graph sine wave

I have this signal :
from math import*
Fs=8000
f=500
sample=16
a=[0]*sample
for n in range(sample):
a[n]=sin(2*pi*f*n/Fs)
How can I plot a graph (this sine wave)?
and create name of xlabel as 'voltage(V)' and ylabel as 'sample(n)'
What code to do this?
I am so thanksful for help ^_^
Setting the x-axis with np.arange(0, 1, 0.001) gives an array from 0 to 1 in 0.001 increments.
x = np.arange(0, 1, 0.001) returns an array of 1000 points from 0 to 1, and y = np.sin(2*np.pi*x) you will get the sin wave from 0 to 1 sampled 1000 times
I hope this will help:
import matplotlib.pyplot as plt
import numpy as np
Fs = 8000
f = 5
sample = 8000
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
plt.plot(x, y)
plt.xlabel('sample(n)')
plt.ylabel('voltage(V)')
plt.show()
P.S.: For comfortable work you can use The Jupyter Notebook.
import matplotlib.pyplot as plt # For ploting
import numpy as np # to work with numerical data efficiently
fs = 100 # sample rate
f = 2 # the frequency of the signal
x = np.arange(fs) # the points on the x axis for plotting
# compute the value (amplitude) of the sin wave at the for each sample
y = np.sin(2*np.pi*f * (x/fs))
#this instruction can only be used with IPython Notbook.
% matplotlib inline
# showing the exact location of the smaples
plt.stem(x,y, 'r', )
plt.plot(x,y)
import numpy as np
import matplotlib.pyplot as plt
F = 5.e2 # No. of cycles per second, F = 500 Hz
T = 2.e-3 # Time period, T = 2 ms
Fs = 50.e3 # No. of samples per second, Fs = 50 kHz
Ts = 1./Fs # Sampling interval, Ts = 20 us
N = int(T/Ts) # No. of samples for 2 ms, N = 100
t = np.linspace(0, T, N)
signal = np.sin(2*np.pi*F*t)
plt.plot(t, signal)
plt.xlabel('Time (s)')
plt.ylabel('Voltage (V)')
plt.show()
import math
import turtle
ws = turtle.Screen()
ws.bgcolor("lightblue")
fred = turtle.Turtle()
for angle in range(360):
y = math.sin(math.radians(angle))
fred.goto(angle, y * 80)
ws.exitonclick()
The window of usefulness has likely come and gone, but I was working at a similar problem. Here is my attempt at plotting sine using the turtle module.
from turtle import *
from math import *
#init turtle
T=Turtle()
#sample size
T.screen.setworldcoordinates(-1,-1,1,1)
#speed up the turtle
T.speed(-1)
#range of hundredths from -1 to 1
xcoords=map(lambda x: x/100.0,xrange(-100,101))
#setup the origin
T.pu();T.goto(-1,0);T.pd()
#move turtle
for x in xcoords:
T.goto(x,sin(xcoords.index(x)))
A simple way to plot sine wave in python using matplotlib.
import numpy as np
import matplotlib.pyplot as plt
x=np.arange(0,3*np.pi,0.1)
y=np.sin(x)
plt.plot(x,y)
plt.title("SINE WAVE")
plt.show()
import matplotlib.pyplot as plt
import numpy as np
#%matplotlib inline
x=list(range(10))
def fun(k):
return np.sin(k)
y=list(map(fun,x))
plt.plot(x,y,'-.')
#print(x)
#print(y)
plt.show()
This is another option
#!/usr/bin/env python
import numpy as np
import matplotlib
matplotlib.use('TKAgg') #use matplotlib backend TkAgg (optional)
import matplotlib.pyplot as plt
sample_rate = 200 # sampling frequency in Hz (atleast 2 times f)
t = np.linspace(0,5,sample_rate) #time axis
f = 100 #Signal frequency in Hz
sig = np.sin(2*np.pi*f*(t/sample_rate))
plt.plot(t,sig)
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.tight_layout()
plt.show()
Yet another way to plot the sine wave.
import numpy as np
import matplotlib
matplotlib.use('TKAgg') #use matplotlib backend TKAgg (optional)
import matplotlib.pyplot as plt
t = np.linspace(0.0, 5.0, 50000) # time axis
sig = np.sin(t)
plt.plot(t,sig)
from math import *
Fs = 8000
f = 500
sample = 16
a = [0] * sample
for n in range(sample):
a[n] = sin(2*pi*f*n/Fs)
creating the x coordinates
Sample = [i for i in range(sample)]
importing matplotlib for plotting
import matplotlib.pyplot as plt
adding labels and plotting
plt.xlabel('Voltage(V)')
plt.ylabel('Sample(n)')
plt.plot(Sample, a)
plt.show()