Error in exponential PDF - python-2.7

I need to complete the function exponentialPDF but get an error:
'IndexError: index 0 is out of bounds for axis 0 with size 0'
The function looks like this:
def uniformPDF(x,a=0.0,b=4.0):
p = 1.0/(b-a)*ones((len(x),))
p[x<a] = 0.0
p[x>b] = 0.0
return(p)
def exponentialPDF(x,a=1.0):
"""
Call:
p = exponentialPDF(x,a)
Input argument:
vals: float (array)
Output argument:
p: float (array)
Examples:
In[1]: exponentialPDF([1,2],3)
Out[1]: array([ 0.14936121, 0.03332699])
"""
p = a * exp(-a*x)
p[x<0] = 0.0
return(p)
Can someone help me with the error?

Sounds like the list you are passing in to your function is empty. Read about python lists and see the following post:
IndexError: list assignment index out of range
I found the function works using numpy array, e.g. p = exponentialPDF(np.array([1,2]),3). Hope this help, you should check out the SO homework post and ask again if you're still stuck.
EDIT: As you are using numpy, I would add an explicit convert to numpy array in the function as follows:
def exponentialPDF(x,a=1.0):
"""
Call:
p = exponentialPDF(x,a)
Input argument:
vals: float (array)
Output argument:
p: float (array)
Examples:
In[1]: exponentialPDF([1,2],3)
Out[1]: array([ 0.14936121, 0.03332699])
"""
if type(x) is list:
x = array(x)
p = a * exp(-a*x)
p[x<0] = 0.0
return(p)
Hopefully this will fix your problem and you can use the function as needed (assuming returning a numpy array from the function is okay).

Related

Lambdifying a function with conditon statements using sympy

Im trying to lambdify this function
def f(x):
if ceil(x)%2 == 0:
return -1
else :
return +1
a = sympy.lambdify(x,f(x))
Im getting an error when i try to do that.
I also tried piecewise , but it is not giving me the desired outcome
y = lambdify(x,(Piecewise((1, ceil(x)%2 == 0), (-1,True))))
Please help
Thanks in advance
You need to pass a symbolic expression to lambdify so a Python function is no good. Also you need to use symbolic sympy functions and sympy's ceil function is actually called ceiling. Finally == compares if two expressions are the same which is not the same as constructing a symbolic Boolean. For that you need Eq:
That gives
In [19]: p = Piecewise((1, Eq(ceiling(x)%2, 0)), (-1,True))
In [20]: p
Out[20]:
⎧1 for ⌈x⌉ mod 2 = 0
⎨
⎩-1 otherwise
In [21]: y = lambdify(x, p)
In [22]: y([1, 2, 3])
Out[22]: array([-1., 1., -1.])
References:
https://docs.sympy.org/latest/modules/functions/elementary.html#ceiling
https://docs.sympy.org/latest/tutorial/gotchas.html#equals-signs

How to handle PySpark UDF return values in different types?

I have a data frame with one column. In each row of this data frame, there is a list. For example :
df = spark.createDataFrame(
[
[[13,23]],
[[55,65]],
],
['col',]
)
Then I defined a UDF which basically adds 1 to first number in the list and add 1.5 to the second number of the list.
def calculate(mylist) :
x = mylist[0] + 1
y = mylist[1] + 1.5
return x,y
The problem is that when I apply this function to my data frame it returns the X value but it does not return the Y value.
I think it is because the Y value is not an integer.
This is the way that I do this.
import pyspark.sql.functions as F
from pyspark.sql.types import IntegerType, ArrayType
func = F.udf(lambda x: calculate(x), ArrayType(IntegerType()))
df.withColumn('vals', func('col')).show()
What can I do to get the Y value as well as X value? I simplified the UDF and sample data frame for the sake of being easy to understand and solve.
calculate udf is returning integer and also float type with the given input.
If your use case first value is integer and second value is float, you can return StructType
If both need to be same type, you can use the same code and change calculate udf which returns both integers
func = F.udf(lambda x: calculate(x), T.StructType(
[T.StructField("val1", T.IntegerType(), True),
T.StructField("val2", T.FloatType(), True)]))

Tensorflow while loop : dealing with lists

import tensorflow as tf
array = tf.Variable(tf.random_normal([10]))
i = tf.constant(0)
l = []
def cond(i,l):
return i < 10
def body(i,l):
temp = tf.gather(array,i)
l.append(temp)
return i+1,l
index,list_vals = tf.while_loop(cond, body, [i,l])
I want to process a tensor array in the similar way as described in the above code. In the body of the while loop I want to process the array by element by element basis to apply some function. For demonstration, I have given a small code snippet. However, it is giving an error message as follows.
ValueError: Number of inputs and outputs of body must match loop_vars: 1, 2
Any help in resolving this is appreciated.
Thanks
Citing the documentation:
loop_vars is a (possibly nested) tuple, namedtuple or list
of tensors that is passed to both cond and body
You cannot pass regular python array as a tensor. What you can do, is:
i = tf.constant(0)
l = tf.Variable([])
def body(i, l):
temp = tf.gather(array,i)
l = tf.concat([l, [temp]], 0)
return i+1, l
index, list_vals = tf.while_loop(cond, body, [i, l],
shape_invariants=[i.get_shape(),
tf.TensorShape([None])])
The shape invariants are there, because normally tf.while_loop expects the shapes of tensors inside while loop won't change.
sess = tf.Session()
sess.run(tf.global_variables_initializer())
sess.run(list_vals)
Out: array([-0.38367489, -1.76104736, 0.26266089, -2.74720812, 1.48196387,
-0.23357525, -1.07429159, -1.79547787, -0.74316853, 0.15982138],
dtype=float32)
TF offers a TensorArray to deal with such cases. From the doc,
Class wrapping dynamic-sized, per-time-step, write-once Tensor arrays.
This class is meant to be used with dynamic iteration primitives such as while_loop and map_fn. It supports gradient back-propagation via special "flow" control flow dependencies.
Here is an example,
import tensorflow as tf
array = tf.Variable(tf.random_normal([10]))
step = tf.constant(0)
output = tf.TensorArray(dtype=tf.float32, size=0, dynamic_size=True)
def cond(step, output):
return step < 10
def body(step, output):
output = output.write(step, tf.gather(array, step))
return step + 1, output
_, final_output = tf.while_loop(cond, body, loop_vars=[step, output])
final_output = final_output.stack()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(final_output))

Cumulative distribution function (hypergeometric)

I need to find out how to calculate the 'hypergeometric cdf':
I know how the function looks like and how it works but I have a few problems tipping the function into python:
def hypergeometricCDF(N,K,n,x):
"""
Call:
p = hypergeometricCDF(N,K,n,x)
Input argument:
N: integer
K: integer
n: integer
x: integer
Output argument:
p: float
Example:
hypergeometricCDF(120,34,12,7)
=>
0.995786
"""
f=sum(range(x+1))
p = log_binomial_coeff(N-K,n-f) + log_binomial_coeff(K,f) - log_binomial_coeff(N,n)
return(p)
The problem is, how do I integrate the sum function from i to x? I tried it with sum(range(x+1)) but it won't work.
Try this:
def hypergeometricCDF(N,K,n,x):
"""
Call:
p = hypergeometricCDF(N,K,n,x)
Input argument:
N: integer
K: integer
n: integer
x: integer
Output argument:
p: float
Example:
hypergeometricCDF(120,34,12,7)
=>
0.995786
"""
k = arange(x+1)
p = sum(exp(log_hypergeometricPMF(N,K,n,k)))
return(p)
log_hypergeometricPMF is defined on top of the file ;)

Returning np.array or np.matrix objects in a theano function

I have to do something like this.
import theano as th
import theano.tensor as T
x, y = T.dscalars('x', 'y')
z = np.matrix([[x*y, x-y], [x/y, x**2/(2*y)]])
f = th.function([x, y], z) # causes error
# next comes calculations like f(2, 1)*f(3, 2)*some_matrix
I know the last line is not a valid code as th.function doesn't support returning these objects. Is there an efficient way to do this without returning all elements of matrix and casting it as an np.matrix?
The problem with your approach is that z needs to be a list of theano variables not a numpy matrix.
You can achieve the same result using:
z1,z2,z3,z4 = x*y,x-y,x/y,x**2/(2*y)
f = th.function([x, y], [z1,z2,z3,z4])
def createz(z1,z2,z3,z4) :
return np.matrix([[z1,z2],[z3,z4]])
print(createz(*f(1,2)))