0

I'm trying to write a function that generates the restrictions of a function g at a given point p.

For example, let's say g(x, y, z) = 2x + 3y + z and p = (5, 10, 15). I'm trying to create a function that would return [lambda x : g(x, 10, 15), lambda y: g(5, y, 15), lambda z: g(5, 10, z)]. In other words, I want to take my multivariate function and return a list of univariate functions.

I wrote some Python to describe what I want, but I'm having trouble figuring out how to pass the right inputs from p into the lambda properly.

def restriction_generator(g, p):
    restrictions = []
    for i in range(len(p)):
        restriction = lambda x : g(p[0], p[1], ..., p[i-1], p[x], p[i+1], .... p[-1])
        restrictions.append(restriction)
    return restrictions

Purpose: I wrote a short function to estimate the derivative of a univariate function, and I'm trying to extend it to compute the gradient of a multivariate function by computing the derivative of each restriction function in the list returned by restriction_generator.

Apologies if this question has been asked before. I couldn't find anything after some searching, but I'm having trouble articulating my problem without all of this extra context. Another title for this question would probably be more appropriate.

bandicoot12
  • 103
  • 2

2 Answers2

2

Since @bandicoot12 requested some more solutions, I will try to fix up your proposed code. I'm not familiar with the ... notation, but I think this slight change should work:

def restriction_generator(g, p):
    restrictions = []
    for i in range(len(p)):
        restriction = lambda x : g(*p[: i], x, *p[i+1:])
        restrictions.append(restriction)
    return restrictions

Although I am not familiar with the ... notation, if I had to guess, your original code doesn't work because it probably always inputs p[0]. Maybe it can be fixed by changing it from p[0], p[1], ..., p[i-1] to p[0], ..., p[i-1].

  • This is great! I was looking for a short lambda expression. The ... notation was just to help express what I was going for, but it didn't work. There's a slight bug in the code, which is resolved by changing the lambda to `lambda x, i=i : g(*p[: i], x, *p[i+1:])` The bug is explained in the posts below, just pasting for reference: https://stackoverflow.com/questions/3431676/creating-functions-or-lambdas-in-a-loop-or-comprehension https://stackoverflow.com/questions/452610/how-do-i-create-a-list-of-lambdas-in-a-list-comprehension-for-loop?noredirect=1&lq=1 – bandicoot12 Sep 03 '22 at 04:24
1

try something like this:

def foo(fun, p, i):
    def bar(x):
        p[i] = x
        return fun(*p)
    return bar

and

def restriction_generator(g, p):
    restrictions = []
    for i in range(len(p)):
        restrictions.append(foo(g, p, i))
    return restrictions
ACA
  • 151
  • 6
  • Nice! This was less tricky than I thought; I shouldn't have focused on using a lambda for this. Thanks for the help :) – bandicoot12 Sep 03 '22 at 03:16