I have the following code:
from scipy.interpolate import UnivariateSpline
from scipy.optimize import fmin
a = UnivariateSpline(b,c) #Python
d = fmins(#(t) -ppval(a,t), someexpression); #Matlab where fmin is equivalent to fmins
How translate it to Python3?
#(t) -ppval(a,t) in Matlab is an anonymous function
You can denote things similarly using a lambda function in python.
By teh example here I see that the output of the UnivariateSpline
is callable, then the python analogous is lambda t: -a(t).
But you will have more problem fmins is not define then you may want to check alternatives in scipy.optimize package.
The documentation of fmin tells us that its first argument must be the function, the second argument the initial value, so it's exactly the same as in MATLAB. In that case you should be able to call
d = fmin(lambda x: -a(x), someexpression)
Related
I am practicing Python from Codewars. One of the questions was to take a function as an input given in string from, differentiate it and use the other input given as an integer and return the result. For example lets say the inputs are
stringf=x**2+2x
inputint=3
def differentiate(stringf,inputint) should return 8. I managed to do this by using Sympy and eval. However when I take the derivate of the function with sympy.diff it converts a regular lambda function to something else which you cannot pass arguments. For example you can do f(1) in below code but you cannot do deffunc(1) it throws the error "TypeError: 'Add' object is not callable" because the type of deffunc becomes "<class 'sympy.core.add.Add'>" after sympy.diff.
def differentiate(equation, point):
import sympy as sym
f=lambda x:equation #turn the string into a formula with x
x= sym.symbols('x')
deffunc=sym.diff(f(x),x) #differentiate with respect to x
strfunc=str(deffunc) #convert the function to a string to be used in eval
x=point
f=eval(strfunc)
return f
I found a workaround by simply converting it to string then using eval but I was wondering is there a better way to pass the 'point' into the 'deffunc'?
I have a list of numpy functions
fcts = [lambda x : np.power(x,2),np.sqrt,lambda x : np.add(x,3.)]
that I want to apply to an input x by chaining, i.e.
np.power(np.sqrt(np.add(x,3.)),2)
(or the other way around)
Is there an intrinsic numpy function for that or what is the most elegant/fastest way to do that (for a large list of functions) instead of
input = np.random.uniform(0,1,(2,3))
for fct in fcts:
input = fct(input)
Edit:
Numpy is written in C++ and I am wondering, wether there is any 'loss in speed' when the results are converted to python between the functions (and assigned to the variable input).
Here, reduce() from the functools module can do the trick, although I believe the underlying behaviour is pretty close to what you did.
import functools
functools.reduce(lambda o, func: func(o), fcts , input_object)
getsourcelines returns the line where the function is defined.
However, if there are more than one function, like in the example below, it returns both, since it always returns the whole line.
import re
from inspect import getsourcelines
def f(f1, f2_is_not_used_now):
lines = getsourcelines(f1)[0]
sets = re.findall('(?={)(.+?)(?<=})', lines[0])
print(sets)
f(lambda x: {x ** 2}, lambda y: {y ** 3})
# output: ['{x ** 2}', '{y ** 3}']
How can I get just the code (i.e., only the source code of the set of f1 in this contrived example) related to the inspected function object?
There is no fool-proof way to find the definition of a function object in the source at runtime since function objects exist as bytecodes at runtime, and trying to pinpoint the exact position in the source code in which the function is defined with string parsing would always come with caveats and would break under certain circumstances.
One of the more robust approaches would be to convert the bytecodes of the function object to Python code using a decompiler such as the uncompyle6 package:
from uncompyle6.main import decompile
from io import StringIO
def f(f1, f2_is_not_used_now):
out = StringIO()
decompile(bytecode_version=None, co=f1.__code__, out=out)
print(out.getvalue())
f(lambda x: {x ** 2}, lambda y: {y ** 3})
This outputs (sans the comments):
return {
x ** 2}
which isn't exactly the original source code that defines the function with a lambda call, but would give you its equivalent function converted from the bytecodes.
Demo: https://replit.com/#blhsing/PoisedGleamingField
Im trying to replace the sympy function x(t) to the sympy symbol x.
It should be like something like this:
Before the replace:
funcion0=t**2*sp.cos((x(t)/2))
After the replace:
funcion1=t**2*sp.cos((x/2))
import sympy as sp
t = sp.Symbol('t')
x = sp.Function('x')
funcion=t**2*sp.cos((x(t)/2))
def replace(funcion):
funcion1=funcion.subs(x(t), x)
return funcion1
I know that doesnt work, but maybe it helps to understand what im saying hahaha.
Thanks!!!!
When working with SymPy, it's best to keep in mind the differences between functions, symbols and physical numbers like floats or ints. Here, you want the function x (evaluated at t) to be substituted with the symbol x. If you are uncertain at any point, it is best to add what the type of the variable to its name as I have done below:
import sympy as sp
t, x_sym = sp.symbols('t x')
x_func = sp.Function('x')
function = t**2*sp.cos((x_func(t)/2))
def replace(funcion):
function1 = funcion.subs(x_func(t), x_sym)
return function1
print(replace(function))
It should give you the desired result.
I'm still learning the various uses for class methods. I have some code that performs linear regression. So I decided to make a general class called LinRegression and use more specific methods that call the class based on the type of linear regression (i.e use one trailing day, or 5 trailing days etc for the regression).
Anyways, here it goes. I feel like I am doing something wrong here with regards to how I defined the class and am calling the class.
This is from the main.py file:
lin_reg = LinRegression(daily_vol_result)
lin_reg.one_day_trailing()
And this is from the linear_regression file (just showing the one day trailing case):
class LinRegression:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression as lr
from sklearn.metrics import mean_squared_error as mse
from SEplot import se_plot as SE
def __init__(self, daily_vol_result):
"""
:param daily_vol_result: result from def daily_vol_calc
"""
import numpy as np
data = np.asarray(daily_vol_result['Volatility_Daily'])
self.data = data
#classmethod
def one_day_trailing(cls, self):
"""
Compute one day trailing volatility
:return: Mean Squared error, slope: b, and y-int: c
"""
x = self.data[:-1]
y = self.data[1:]
x = x.reshape(len(x), 1)
cls.lr.fit(x, y)
b = cls.lr.coef_[0]
c = cls.lr.intercept_
y_fit1 = b * x + c
MSE1 = cls.mse(y, y_fit1)
print("MSE1 is " + str(MSE1))
print("intercept is " + str(c))
print("slope is " + str(b))
cls.SE(y, y_fit1)
return MSE1, b, c
What I "think" I am doing is that when I call lin_reg, I already have the daily_vol_result passed, then lin_reg.one_day_trailing() should just execute the one_day_trailing def using the self defined in init.
However, I get TypeError: one_day_trailing() missing 1 required positional argument: 'self'. Some other info, the variable, daily_vol_result is a DataFrame and I convert to np array to do the linear regression with sklearn.
Also, when I tried messing around with the code to work, I had an additional issue where the line: lr.fit(x, y) gave me a type error with no positional arg for y. I checked the existence and length of y to see if it matched x and it checks out. I am pretty confused as to how I was only passing one arg.
Your ideas and advice are welcome, thanks!
The thing is, you are using wrong position for self in method one_day_trailing(cls, self). You have specified self at second position in method definition.
If not passed anything and executing the method simply as you did in the 2nd line of code:
lin_reg.one_day_trailing()
the class object self will be passed as first argument, so self is passed in cls argument. And thus, the self argument in one_day_trailing() remains unused.
Interchange the arguments in def like this:-
def one_day_trailing(self, cls):
will be better. But then you need to pass the cls object, whatever it is.
See the following questions to know more:
missing 1 required positional argument:'self'
TypeError: attack() missing 1 required positional argument: 'self'
I found out that the linear regression package was acting like a class and so lr.fit(self, x, y) was what it wanted as an input. I first instantiated the class as:
A = lr(), then A.fit(x,y).
I had this line in my main file:
ASDF = LinRegression.one_day_trailing(daily_vol_result)
I also figured out a more general way to produce these functions. I did not end up needing to use #classmethod or #staticmethod