-
Notifications
You must be signed in to change notification settings - Fork 133
[Linear Algebra] Add eye and svd functions #578
Conversation
Is there a neat way of doing this in swift: m = u.shape[-1]
n = v.shape[-1]
if m <= n:
v = v[..., :m]
else:
u = u[..., :n] |
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.
Could you please add tests for all newly added operations? (setDiagonal
, eye
, svd
)
@dan-zheng could you comment on two things :
m = u.shape[-1]
n = v.shape[-1]
if m <= n:
v = v[..., :m]
else:
u = u[..., :n] |
Making both column count and batch shape optional sounds good, matching public func eye<Scalar: Numeric>(
rowCount: Int,
columnCount: Int? = nil,
batchShape: [Int] = []
) {
let columnCount = columnCount ?? rowCount
...
}
I believe this is equivalent: import TensorFlow
var u = Tensor<Float>(ones: [3, 5, 7])
var v = Tensor<Float>(ones: [3, 5])
let m = u.shape.dimensions.last!
let n = v.shape.dimensions.last!
if m <= n {
v = v[TensorRange.ellipsis, ..<m]
} else {
u = u[TensorRange.ellipsis, ..<n]
} |
/// leading `min(shape[rank - 1], shape[rank - 2])` singular vectors. Ignored if | ||
// `computeUv` is `false`. | ||
@inlinable | ||
func svd(computeUv: Bool = true, fullMatrices: Bool = false |
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.
Can you rename computeUv
to computeUV
, uv
or something more readable? It might follow the language style, but it is slightly obscure, what is meant by computeUv
.
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 I took this variable name from the raw ops generated. I do agree that it sounds sort of vague.
But would like @dan-zheng's idea on this
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 computeUV
is the better name, since Uv
is more easily misinterpreted as one camelcased entity than UV
. Could you please update the parameter name and doc comments?
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.
A semantic name like computeLeftAndRightSingularVectors
may be more idiomatic than computeUV
. I'm not sure what's the best semantic name, so using computeUV
for now sounds good to me, to be consistent with numpy.svd
and tf.linalg.svd
.
I'll add the tests and other changes today. |
Will write eye and set diagonal functions next. |
I'm currently looking at optionality in swift for the eye function, Will write the test as soon as i find a convenient solution. |
@dan-zheng added the tests and todo for eye function optionality. I'll get around to that soon, but did not want to block this PR. |
Don't you think that it would be better if you write eye function like this if we give it input eye(3) or eye(3,3) then it will give the same output but if you give it input as eye(3,2) then output will be There is no batch concept in either numpy or pytorch in eye function but if it is needed then it can be added as. I have implemented it to contribute to swift and tested it on different test cases but since I am new to open source I don't know how to contribute full function code from scratch. |
@SumanSudhir the eye function trying to be replicated is that of tensorflow python. I'll take a look at your approach and implement it tomorrow. |
Hey, @Shashi456 if you don't mind then can I pull request for Some examples of tested input and output
|
@SumanSudhir could you update this function after this PR is merged? That sounds like a better idea. |
@dan-zheng could you review this once more? Also happy new year :) |
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.
Thanks for adding tests for all added operations! I left some more feedback.
@dan-zheng sorry for the trivial formatting errors, I'll have the changes up in a few hours. |
@dan-zheng ping. Built and tested locally. |
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 left some comments that I'll address personally to save time!
Update doc comments for `withDiagonal` and `eye`. Simplify `eye` implementation to avoid premature optimization.
/// leading `min(shape[rank - 1], shape[rank - 2])` singular vectors. Ignored if | ||
// `computeUv` is `false`. | ||
@inlinable | ||
func svd(computeUv: Bool = true, fullMatrices: Bool = false |
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 computeUV
is the better name, since Uv
is more easily misinterpreted as one camelcased entity than UV
. Could you please update the parameter name and doc comments?
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!
It takes a long time to review naming (e.g. argument labels) and API doc comments.
Could you please:
- Follow these naming guidelines.
- Follow these API doc guidelines.
- Follow existing reviewed Swift APIs as a precedent. The API doc comments for
func svd
are a nice example.
That would be greatly appreciated, and would help accelerate the review process!
@dan-zheng, will follow suit for linear algebra functions. Since it was my first time contributing to this area, I wasn't entirely sure of formatting. Sorry! |
So I've not written a test for svd because, I'm not sure how to calculate the permutation for a standard transpose for any given matrix to invokeWill have the test uploaded soon..tranposed
Since for a tolerance check, i'll have to calculate the reconstructed matrix as
u*diag(s) * transpose(v)
.I took inspiration for the eye function from here.
The issue with this implementation though is that
numCols
,batchShape
need to be optional, but there is no convenient way for optional parameters in swift. and declaring it asnumCols: Int? = nil
doesn't exactly compile. So i wanted to ask if i should just overload the function/have multiple function declarations.Finally, added the
setDiagonal
function, it's functionality is different fromset_matrix_diag
of tensorflow because that implementation usessetMatrixDiagV2
which is not available in the rawopsgenerated file.