scale translate function with python decorator - python

I have a list of single parameter functions in python to which I would like to apply the same scaling/translation operation.
The scale/translation for a function f(x) would be as follows:
f'(x, a, b, c, d) = a + b* f( c*(x - d) )
So for example if my original function is defined as:
f(x) = 3*x
I would like to modify it to be:
f'(x, a, b, c, d) = a + b * (3*(c*(x - d)))
Ideally using a decorator (or some other reusable operation that I can apply to each function in the list).
Is there a pythonic way to achieve this such that every transformation doesn't need to be hardcoded for each function I have?
Apologies if the question is unclear - thanks in advance for any suggestions.

def f(x):
return 3*x
def makeFPrime(func):
def inner(x, a, b, c, d):
return a + b * (3*(c*func(x-d)))
return inner
This gives for example:
f2 = makeFPrime(f)
f2(2,1,1,1,2)
1
f2(2,1,1,1,0)
19
Alternatively, use makeFPrime as a decorator:
def makeFPrime(func):
def inner(x, a, b, c, d):
return a + b * (3*(c*func(x-d)))
return inner
#makeFPrime
def f(x):
return 3*x
Then f(2,1,1,1,2) returns 1

Related

optimize.curve_fit: how to bound one parameter respective to another?

When doing (ad hoc example)
from scipy import optimize
def fit_func(x, a, b):
return a*x + b
optimize.curve_fit(fit_func, x_data, y_data)
how can I put bounds like a>b? I know the option bounds, but it appears it does accept only explicit numbers.
Maybe some if in the definition of fit_func?
You can try with a workaround, instead of defining the function as:
def fit_func1(x, a, b):
return a*x + b
with constraint a>b, you can do:
def fit_func2(x, this_much_a_is_bigger_than_b, b):
return (a+this_much_a_is_bigger_than_b)*x + b
with constraint this_much_a_is_bigger_than_b > 0, 0 being an explicit number, and fit_func2 function is equivalent to the fit_func1 from a mathematical perspective.
Then you can have:
a = b + this_much_a_is_bigger_than_b
b = b
Curce_fit only supports box constraints (via least_squares). There are workarounds, but I'd rather change variables to e.g a and b-a

'NoneType' object is not iterable - where is an error?

My aim is to take a triple (A, B, C), compute three "neighbours", and then output the maximum of each of those neighbours to a list.
For example, the neighbours of (sqrt(6), 4*sqrt(3), 9*sqrt(2)) are
(sqrt(3)*sqrt(2), 3*sqrt(2), 4*sqrt(3))
(4*sqrt(3), 35*sqrt(3)*sqrt(2), 9*sqrt(2))
(sqrt(3)*sqrt(2), 9*sqrt(2), 14*sqrt(3))
so the values 14*sqrt(3), 36*sqrt(6), 4*sqrt(3) would be the output.
When I try this:
A = 1*sqrt(6)
B = 4*sqrt(3)
C = 9*sqrt(2)
def nbhs_1(triple):
X = triple[0]
Y = triple[1]
Z = triple[2]
print((X.canonicalize_radical(), (X * Y - Z).canonicalize_radical(), Y.canonicalize_radical()))
def nbhs_2(triple):
X = triple[0]
Y = triple[1]
Z = triple[2]
print((Y.canonicalize_radical(), (Y * Z - X).canonicalize_radical(), Z.canonicalize_radical()))
def nbhs_3(triple):
X = triple[0]
Y = triple[1]
Z = triple[2]
print((X.canonicalize_radical(), Z.canonicalize_radical(), (X * Z - Y).canonicalize_radical()))
result_1 = nbhs_1((A, B, C))
result_2 = nbhs_2((A, B, C))
result_3 = nbhs_3((A, B, C))
print(result_1)
print(result_2)
print(result_3)
l = [max(result_1), max(result_2), max(result_3)]
I get 'NoneType' object is not iterable.
The main problem is that you are not structuring the function properly:
It is recommended that you expose your arguments within the function call. Don't def nbhs_1(triple), do instead def nbhs_1(X, Y, Z). In this way you can actually have one single function that does what you want (easier to maintain)
Return your result. At the moment you are printing the outcome of the function call but you are not returning those results.
I'm also not sure the canonicalize_radical() call is also done properly. Python is object-oriented and by writing var.canonicalize_radical() you are inferring that var should itself know about this function (e.g. the function is part of var) but that sounds wrong. The correct call may be canonicalize_radical(var)
Basically, this should be closer to a correct solution:
A=1*sqrt(6)
B=4*sqrt(3)
C=9*sqrt(2)
def nbhs(X, Y, Z):
out1 = canonicalize_radical(X)
out2 = canonicalize_radical(X*Y-Z)
out3 = canonicalize_radical(Y)
return out1, out2, out3
l = [max(nbhs(A, B, C)), max(nbhs(B, A, C)), max(nbhs(C, B, A))]
The problem is that you are not calling the functions nbhs_1, nbhs_2, and nbhs_3 and also the functions aren't returning any values
from math import sqrt
A=1*sqrt(6)
B=4*sqrt(3)
C=9*sqrt(2)
triple = (A, B, C)
def nbhs_1(triple):
X=triple[0]
Y=triple[1]
Z=triple[2]
return (X.canonicalize_radical(),(X*Y-Z).canonicalize_radical(),Y.canonicalize_radical())
def nbhs_2(triple):
X=triple[0]
Y=triple[1]
Z=triple[2]
return (Y.canonicalize_radical(),(Y*Z-X).canonicalize_radical(),Z.canonicalize_radical())
def nbhs_3(triple):
X=triple[0]
Y=triple[1]
Z=triple[2]
return (X.canonicalize_radical(),Z.canonicalize_radical(),(X*Z-Y).canonicalize_radical())
l=[max(nbhs_1(triple)),max(nbhs_2(triple)),max(nbhs_3(triple))]

Evaluate Derivative of Function at a Point Python 2.7

I have the following function:
import sympy as sp
def inverted(q, m, a, nu):
return (-1)**(m+1)*(a/m)**m*sp.exp(m)*q**(-nu)*sp.diff(1/(sp.sqrt(a**2+q**2))*(sp.sqrt(a**2+q**2)-a)**(nu), a, m+1)
I want to define some lambda function such that
f100 = lambda a, q: inverted(q, 100, a, 0)
However, when I try to examine
q = sp.symbols('q')
f100(1000.0, q)
I get the following output:
ValueError:
Can't calculate 101st derivative wrt 10.
Obviously, what is happening is when I call f100(1000.0, q), the function refers back to inverted and the issue arises. I was hoping for a way around this.
Seems like you have to make a a variable first so diff works. It doesn't work if you fix a before (I think because you differentiate with respect to a). You can substitute a with 1000 afterwards.
import sympy as sp
def inverted(q, m, a, nu):
return (-1)**(m+1)*(a/m)**m*sp.exp(m)*q**(-nu)*sp.diff(1/(sp.sqrt(a**2+q**2))*(sp.sqrt(a**2+q**2)-a)**(nu), a, m+1)
f100 = lambda a, q: inverted(q, 100, a, 0)
q, a = sp.symbols('q, a')
print(f100(a, q).subs(a, 1000))

SymPy: Evaluate given expression with given variables

I have a sympy expression involving two variables a, b. I would now like to evaluate this expression for specific values of a and b. Using a lambda like
import sympy
def get_expression(a, b):
# Complex function with a simple result. I have no control here.
return a*b + 2
a = sympy.Symbol('a')
b = sympy.Symbol('b')
z = get_expression(a, b)
f = lambda a, b: z
print(f(1, 1))
only gives
a*b + 2
though.
Any hints?
Turns out that lambdify is what I need:
f = sympy.lambdify([a, b], z)
print(f(1, 1))

return function in python

I want to write script to calculate the volume. The first function calculates area of the base. The second takes this value and multiply it with the height. Then I'd like to write the value of the volume. Where is the mistake?
def base_area(a, b):
a = 2
b = 3
s = a * b
return s
def volume(s):
h = 7
V = h * s
print (V)
It doesn't make sense to pass a, b as parameters to base_area() function, because inside, you are assigning constant values to a and b. That method should look like:
def base_area(a, b):
s = a * b
return s
so you use the values passed. This function can be written in a more concise way:
def base_area(a, b):
return a * b
Then the volume() method should receive 3 parameters, a, b and h(height):
def volume(a, b, h):
return base_area(a, b) * h
Here, you are calling base_area() passing a and b. From this call, you get the area, so you multiply it by h and return it.
Test:
print volume(2, 3, 7)
>>> 42

Categories

Resources