Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding lambda functions with the same operator in python

I have a rather lengthy equation that I need to integrate over using scipy.integrate.quad and was wondering if there is a way to add lambda functions to each other. What I have in mind is something like this

y = lambda u: u**(-2) + 8
x = lambda u: numpy.exp(-u)
f = y + x
int = scipy.integrate.quad(f, 0, numpy.inf)

The equations that I am really using are far more complicated than I am hinting at here, so for readability it would be useful to break up the equation into smaller, more manageable parts.

Is there a way to do with with lambda functions? Or perhaps another way which does not even require lambda functions but will give the same output?

like image 448
coffeepls Avatar asked Dec 14 '15 07:12

coffeepls


People also ask

Can a lambda function have multiple expressions in Python?

Lambda functions are anonymous functions that can contain only one expression.

Can lambda take two arguments Python?

A lambda function can take any number of arguments, but can only have one expression.

Can lambda have multiple expressions?

Lambda functions can only have one expression in their body. Regular functions can have multiple expressions and statements in their body. Lambdas do not have a name associated with them. That's why they are also known as anonymous functions.


2 Answers

There's no built-in functionality for that, but you can implement it quite easily (with some performance hit, of course):

import numpy

class Lambda:

    def __init__(self, func):
        self._func = func

    def __add__(self, other):
        return Lambda(
            lambda *args, **kwds: self._func(*args, **kwds) + other._func(*args, **kwds))

    def __call__(self, *args, **kwds):
        return self._func(*args, **kwds)

y = Lambda(lambda u: u**(-2) + 8)
x = Lambda(lambda u: numpy.exp(-u))

print((x + y)(1))

Other operators can be added in a similar way.

like image 39
fjarri Avatar answered Oct 13 '22 02:10

fjarri


In Python, you'll normally only use a lambda for very short, simple functions that easily fit inside the line that's creating them. (Some languages have other opinions.)

As @DSM hinted in their comment, lambdas are essentially a shortcut to creating functions when it's not worth giving them a name.

If you're doing more complex things, or if you need to give the code a name for later reference, a lambda expression won't be much of a shortcut for you -- instead, you might as well define a plain old function.

So instead of assigning the lambda expression to a variable:

y = lambda u: u**(-2) + 8

You can define that variable to be a function:

def y(u):
    return u**(-2) + 8

Which gives you room to explain a bit, or be more complex, or whatever you need to do:

def y(u):
    """
    Bloopinate the input

    u should be a positive integer for fastest results.
    """
    offset = 8
    bloop = u ** (-2)
    return bloop + offset

Functions and lambdas are both "callable", which means they're essentially interchangable as far as scipy.integrate.quad() is concerned.

To combine callables, you can use several different techniques.

def triple(x):
   return x * 3

def square(x):
   return x * x

def triple_square(x):
   return triple(square(x))

def triple_plus_square(x):
    return triple(x) + square(x)

def triple_plus_square_with_explaining_variables(x):
    tripled = triple(x)
    squared = square(x)
    return tripled + squared

There are more advanced options that I would only consider if it makes your code clearer (which it probably won't). For example, you can put the callables in a list:

 all_the_things_i_want_to_do = [triple, square]

Once they're in a list, you can use list-based operations to work on them (including applying them in turn to reduce the list down to a single value).

But if your code is like most code, regular functions that just call each other by name will be the simplest to write and easiest to read.

like image 113
RJHunter Avatar answered Oct 13 '22 00:10

RJHunter