| // sVec produced by svd() has minimal dim length (no extra zeroes). | ||
| // Thus s+ produced by diagCreate() will have minimal dims as well, | ||
| // and v could have an extra dim0 or u* could have an extra dim1 | ||
| if (v.dims()[1] > sPinvCast.dims()[0]) { |
| Array<T> v = transpose(vT, true); | ||
|
|
||
| // Round down small values to zero to avoid large reciprocals later | ||
| Array<Tr> eps = createValueArray<Tr>(sVec.dims(), scalar<Tr>(1e-6)); |
| } | ||
| if (uT.dims()[0] > sPinvCast.dims()[1]) { | ||
| std::vector<af_seq> seqs = { | ||
| {0., static_cast<double>(sPinvCast.dims()[1]), 1.}, |
| */ | ||
| AFAPI array inverse(const array &in, const matProp options = AF_MAT_NONE); | ||
|
|
||
| /** |
| #include <svd.hpp> | ||
| #include <transpose.hpp> | ||
|
|
||
| using af::dim4; |
| } | ||
|
|
||
| double validTol = tol; | ||
| if (validTol < 0.) { |
|
|
||
| \brief Pseudo-invert a matrix | ||
|
|
||
| This function calculates the Moore-Penrose pseudoinverse of a matrix \f$A\f$, using \ref af::svd at its core. If \f$A\f$ is of size **M x N**, then its pseudoinverse \f$A^+\f$ will be of size **N x M**. |
| \param[in] options determining various properties of matrix \p in | ||
| \returns \p x, the inverse of the input matrix | ||
|
|
||
| \note \p tol is not the actual lower threshold, but it is passed in as a parameter to the calculation of the actual threshold relative to the shape and contents of \p in. |
| @@ -0,0 +1,170 @@ | |||
| /******************************************************* | |||
| * Copyright (c) 2014, ArrayFire | |||
| Array<T> pinverseSvd(const Array<T> &in, const double tol) | ||
| { | ||
| // Moore-Penrose Pseudoinverse | ||
|
|
| } | ||
|
|
||
| ARG_ASSERT(1, i_info.isFloating()); // Only floating and complex types | ||
| ARG_ASSERT(2, tol >= 0.); // Only floating and complex types |
|
|
||
| // Test Moore-Penrose conditions | ||
| // See https://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_inverse#Definition | ||
|
|
|
|
||
| This function calculates the Moore-Penrose pseudoinverse of a matrix \f$A\f$, using \ref af::svd at its core. If \f$A\f$ is of size **M x N**, then its pseudoinverse \f$A^+\f$ will be of size **N x M**. | ||
|
|
||
| This calculation can be batched if the input array is three-dimensional (**M x N x P**). Each **M x N** slice along the third dimension will have its own pseudoinverse, for a total of **P** pseudoinverses in the output array (**N x M x P**). |
| \param[in] in is the input matrix | ||
| \param[in] tol defines the lower threshold for singular values from SVD | ||
| \param[in] options determining various properties of matrix \p in | ||
| \returns \p x, the inverse of the input matrix |
|
|
||
| \param[in] in is the input matrix | ||
| \param[in] tol defines the lower threshold for singular values from SVD | ||
| \param[in] options determining various properties of matrix \p in |
| {0., static_cast<double>(inArray.dims()[1] - 1), 1.}, | ||
| {static_cast<double>(i), static_cast<double>(i), 1.} | ||
| }; | ||
| Array<T> inSlice = createSubArray<T>(inArray, seqs); |
mark-poscablo added 2 commits
September 12, 2018 15:26
| Array<T> vT = createValueArray<T>(dim4(N, N, P, Q), scalar<T>(0)); | ||
| Array<Tr> sVec = createValueArray<Tr>(dim4(min(M, N), 1, P, Q), scalar<Tr>(0)); | ||
| for (uint j = 0; j < Q; ++j) { | ||
| for (uint i = 0; i < P; ++i) { |
9prady9 pushed a commit that referenced this pull request
Nov 3, 2018