-2

Can I use lambda function with numpy's eig function?

Test problem:

import numpy as np
class c1:
    def __init__(self):
        self.mat1 = lambda num1:np.array([[num1,2],[3,4]])
        self.mat2 = np.array([[1,2],[3,4]])
        self.eigVal, self.eigVec = lambda num1:np.linalg.eig(self.mat2+self.mat1(num1))
    def func1(self):
        print(self.mat1(10))
        print(self.eigVal(10))
c1().func1()       

Error is TypeError: cannot unpack non-iterable function object.

4
  • lambda is a single function, and when you call it a single array that contains two arrays is produced. You cannot unpack that directly in the class, but you can do something like self.eigFunc = lambda num1: np.linalg.eig(self.mat2 + self.mat1(num1)) and unpack the results later eigval, eigvec = self.eigFunc(10) Commented Mar 25, 2021 at 9:40
  • Interstingly, this answer says that you can return two values using lambda. But in my example I cant. When I adopt your suggestion its work. Thank you. Commented Mar 25, 2021 at 13:57
  • The lambda when called can return 2 values, but the lambda itself is one object. Commented Mar 25, 2021 at 15:59
  • Thanks, @hpaulj. Now I understand non-iterable structure of lambdaafter I get error from the code below. self.eigFunc = lambda num1: np.linalg.eig(self.mat1(num1)); self.eigenVal = lambda num1 : self.eigFunc(num1) Commented Mar 25, 2021 at 16:04

2 Answers 2

1

This code will get the eigen values and eigen vectors for each of the matrices:

import numpy as np

class c1:
    def __init__(self):
        self.mat1 = np.array([[11,21],[31,41]])
        self.mat2 = np.array([[1,2],[3,4]])
        
        mat1_vals, mat2_vals = list(map(lambda mat: np.linalg.eig(mat), [self.mat1, self.mat2]))
        
        self.eigVal = [mat1_vals[0], mat2_vals[0]]
        self.eigVec = [mat1_vals[1], mat2_vals[1]]
        
        print('Eig Vals: ', self.eigVal)
        print('Eig Vecs:', self.eigVec)

if __name__=='__main__':
    c1()

Output

Eig Vals:  [array([-3.59729717, 55.59729717]), array([-0.37228132,  5.37228132])]
Eig Vecs: [array([[-0.82111408, -0.42601354],
       [ 0.57076411, -0.90471679]]), array([[-0.82456484, -0.41597356],
       [ 0.56576746, -0.90937671]])]


Thing to note is that you have to map the lambda function on some iterable object and then turn the map object into iterable to use it.

Cheers.

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for your answer. As I can understand, there is not any simple way to recursively call eig function with lambda function. I mean, my essential code has NxN matrix.
You are welcome, I hope I helped, but I really don't understand what do you mean by recursively in this situation. What are your constraints in this case? I mean is it execution time or readability or memory resources? You should explain all this in the question, because it is not very clear.
In your answer, self.mat1 is constant, but in my question I tried to put lambda in the self.mat1's first element. What I want is writing a lambda function that depends on first value of self.mat1 matrix and then I want to find eigenvalues of self.mat matrix. I said recursively, because I defined a lambda function for self.mat1 and then I try to create a lambda function which is calling another lambda function. Isn't it recursively means?
Recursive means that you call a function x in side function x itself, in your case self.mat1 is created in the first line of the __init__, then in line 3 you try to assign a newly created lambda again to two variables self.eigVal and self.eigVec, which fails. Then the c1::func1 method is called on integer 10. I really dont see here a recursion, sorry. In addition, to use recursion, you have to define stopping condition, to prevent an infinite recursion, which is missing in your code also.
Oh, I see. Thank you again for your explanation.
0

Thanks to @pietro. The solution is given in this comment.

Here is my working solution.

import numpy as np
class c1:
    def __init__(self):
        self.mat1 = lambda num1:np.array([[num1,2],[3,4]])
        self.mat2 = np.array([[1,2],[3,4]])
        self.eigFunc = lambda num1: np.linalg.eig(self.mat2 + self.mat1(num1))
    def func1(self):
        eigval, eigvec = self.eigFunc(10)
        print(eigval)
c1().func1()

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.