1

I am working on a project that requires a function (I'll call it target) that will take an input named parameter_vector and will output an equation for other functions to take as an input. The output equation I am using as a test case is the standard quadratic equation:

Ax^2 + Bx + C

My target function will take a parameter_vector in that looks like:

parameter_vector = [A, B, C]

and will use these indices as coefficients in writing out my equation as an output. Here is my code so far:

def target(parameter_vector):
    pv = parameter_vector
    x = pv[0]*x**2 + pv[1]*x + pv[2]
    return x

As I'm sure you can guess, the following error pops up in my shell:

UnboundLocalError: local variable 'x' referenced before assignment

So I did a little research and came across the lambda variable that is used for place-holding a variable. I tried to input:

x = pv[0]*lambda**2 + pv[1]*x +pv[2]

But this popped up:

File "source_parameters.py", line 7
x = pv[0]*lambda**2 + pv[1]*lambda +pv[2]
               ^
SyntaxError: invalid syntax

Am I approaching this completely wrong? I'm sure even sure whether the output should be a string or not. Any help would be greatly appreciated!

2 Answers 2

2

You misunderstood how lambdas work; they create a function from an expression. Given x as input, that'd look like this:

lambda x: pv[0]*x**2 + pv[1]*x + pv[2]

The expression produces a function object, which you can return directly from your target() function:

def target(pv):
    return lambda x: pv[0]*x**2 + pv[1]*x + pv[2]

You could unpack the parameter_vector into the three components first to make it clearer you need to have 3 values in it:

def target(parameter_vector):
    a, b, c = parameter_vector
    return lambda x: a * x ** 2 + b * x + c

or you can generalise this to any length of parameter_vector:

def target(parameter_vector):
    return lambda x: sum(p * x ** (len(parameter_vector) - i - 1)
                         for i, p in enumerate(parameter_vector))

Quick demo:

>>> lambda x: pv[0]*x**2 + pv[1]*x + pv[2]
<function <lambda> at 0x102a0c6e0>
>>> def target(parameter_vector):
...     a, b, c = parameter_vector
...     return lambda x: a * x ** 2 + b * x + c
... 
>>> new_function = target([3, 2, 5]) # 3x^2 + 2x + 5
>>> new_function
<function <lambda> at 0x102a0c7d0>
>>> new_function(2)
21
>>> new_function(3)
38
>>> new_function(4)
61
>>> def target(parameter_vector):
...     return lambda x: sum(p * x ** (len(parameter_vector) - i - 1)
...                          for i, p in enumerate(parameter_vector))
... 
>>> new_function = target([3, 2, 5])
>>> new_function(2)
21
>>> new_function = target([3, 2, 5, -2])  # 3x^3 + 2x^2 + 5x - 2
>>> new_function(2)
40
Sign up to request clarification or add additional context in comments.

4 Comments

Great! That is exactly what I am looking for. Is there a way to define an unknown number of indices in place of a,b,c for a more complex function? Let's say it has 12 coefficients but isn't known to the function prior to importing a different script. Is there a way to generalize each index but still use the unpacking step?
@ibanez221: no, unpacking won't let you do that. You'd have to use a sum() of the parameters, each multiplied with x to the power len(parameter_vector) - index (where index is the index of the current parameter): lambda x: sum(p * x ** (len(pv) - i - 1) for i, p in enumerate(pv)).
@ibanez221: added that option to the answer.
Thank you so much! I never would have come up with that solution. This is very helpful, I appreciate it.
2

You're on the right track. You can return a lambda function as follows.

def target(pv):
    return lambda i : pv[0]*i*i + pv[1]*i + pv[2]

Testing that we do get a function back

>>> target([1,3,4])
<function target.<locals>.<lambda> at 0x029E8DB0>

Let's assign the function to f

>>> f = target([1,3,4])

Now we can call the function with an argument

>>> f(5)
44

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.