-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Lang] Add ti.eig for 2x2 matrices #2303
Conversation
else: | ||
lambda1 = ti.Vector([tr, ti.sqrt(-gap)]) * 0.5 | ||
lambda2 = ti.Vector([tr, -ti.sqrt(-gap)]) * 0.5 | ||
A1r = A - lambda1[0] * ti.Matrix.identity(dt, 2) | ||
A1i = -lambda1[1] * ti.Matrix.identity(dt, 2) | ||
A2r = A - lambda2[0] * ti.Matrix.identity(dt, 2) | ||
A2i = -lambda2[1] * ti.Matrix.identity(dt, 2) | ||
v1 = ti.Vector([A2r[0, 0], A2i[0, 0], A2r[1, 0], | ||
A2i[1, 0]]).cast(dt).normalized() | ||
v2 = ti.Vector([A1r[0, 0], A1i[0, 0], A1r[1, 0], | ||
A1i[1, 0]]).cast(dt).normalized() | ||
eigenvalues = ti.Matrix.rows([lambda1, lambda2]) | ||
eigenvectors = ti.Matrix.cols([v1, v2]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is one thing that needs to be discussed. From my knowledge, taichi doesn't have such a datatype to represent complex numbers, which could be generated by eigensolvers.
Currently, I use 2 numbers to store the real part and imaginary part of a complex number. That is to say, for a 2x2 matrix, function ti.eig()
returns a 2x2 matrix v and a 4x2 matrix w. Each row of matrix v stores one eigenvalue represented by a 2d vector for its real and imaginary part. Each column of w stores one eigenvector with 2 entries each represented by two numbers for its real and imaginary part. I'm not sure whether this is the best way to handle this problem. Is there any advice on this? @k-ye
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Yeah this sounds good, thanks! Could you write this as the docstring?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! LGTM + nits
python/taichi/lang/__init__.py
Outdated
if dt is None: | ||
dt = impl.get_runtime().default_fp | ||
from .linalg import eig | ||
return eig(A, dt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this style is probably following how svd()
is implemented, it could be a bit confusing to have multiple eig()
symbols. I'd suggest to change to this:
def eig(A, dt=None):
if dt is None:
dt = impl.get_runtime().default_fp
from taichi.lang import linalg
if A.n == 2:
return linalg.eig2x2(A, dt)
raise Exception("Eigen solver only supports 2D matrices.")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. I will change to this and commit my implementation of sym_eig3x3()
together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think it's better to split into two PRs. This makes the review process easier ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I'll fix it.
else: | ||
lambda1 = ti.Vector([tr, ti.sqrt(-gap)]) * 0.5 | ||
lambda2 = ti.Vector([tr, -ti.sqrt(-gap)]) * 0.5 | ||
A1r = A - lambda1[0] * ti.Matrix.identity(dt, 2) | ||
A1i = -lambda1[1] * ti.Matrix.identity(dt, 2) | ||
A2r = A - lambda2[0] * ti.Matrix.identity(dt, 2) | ||
A2i = -lambda2[1] * ti.Matrix.identity(dt, 2) | ||
v1 = ti.Vector([A2r[0, 0], A2i[0, 0], A2r[1, 0], | ||
A2i[1, 0]]).cast(dt).normalized() | ||
v2 = ti.Vector([A1r[0, 0], A1i[0, 0], A1r[1, 0], | ||
A1i[1, 0]]).cast(dt).normalized() | ||
eigenvalues = ti.Matrix.rows([lambda1, lambda2]) | ||
eigenvectors = ti.Matrix.cols([v1, v2]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Yeah this sounds good, thanks! Could you write this as the docstring?
The CI of GPU failed but I have no idea about the error. It seems the error is not related to my changes, is it? |
No, it's an issue on the CI bot itself #2307 .. |
Related issue = #2208, #2293
[Click here for the format server]
This PR aims to implement utility functions
ti.eig()
for 2x2 matrices as described in #2293.