-
-
Notifications
You must be signed in to change notification settings - Fork 198
Adding Generalized Inverse #2225
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
Merged
Merged
Changes from all commits
Commits
Show all changes
122 commits
Select commit
Hold shift + click to select a range
b5ed86e
Added generalized_inverse files
spinkney 16698b2
finished genealized_inverse test
spinkney 5939422
added generalized_inverse in fun.hpp
spinkney d3337c2
fixed docs on generalized_inverse
spinkney fdc6c1b
update
1c8a51e
Added generalized_inverse files
spinkney 172f7e9
finished genealized_inverse test
spinkney 32ec517
added generalized_inverse in fun.hpp
spinkney 270dde6
fixed docs on generalized_inverse
spinkney 037ca41
update
b28f7a8
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney 21cbcc1
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot aeb78b5
Fixed function doc
spinkney 2192b90
Update test/unit/math/prim/fun/generalized_inverse_test.cpp
spinkney bc58200
Changed -1 to Eigen::Dynamic
spinkney 5ce3276
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot a862f36
Using chol2inv adds a bit more numerical stability
spinkney 48fbbf2
resolved merge conflict
spinkney fedfd8a
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 0e6a898
fixed small typo
spinkney 01e97fa
resolved merge conflict
spinkney e2fc0f9
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 5601b00
optimizing the algebra
spinkney 9066a94
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 86d67ec
Added jitter alias and extra test
spinkney cd1e20e
Merge commit '089db8e9b3ebc2ae65ef4321ebd0652205f31b82' into HEAD
yashikno 664c4fa
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 0b77326
typos
spinkney 2792baa
test fix
spinkney 9788f2a
fixed test matrix
spinkney 836ba0e
clean up docs
spinkney 6718fe2
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 37269e6
adding mix test
spinkney 9253b7c
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney 73dd639
Merge commit 'e98bfbdb70d66f3b28148d400ef197219b0a467b' into HEAD
yashikno 192f4e2
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 248d33f
typo
spinkney cbb6ace
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney 26d018e
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot a1024b6
Merge remote-tracking branch 'origin/feature/ginv' into feature/ginv
spinkney 5a21f25
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot ec2be99
updated mix test
spinkney 61a193d
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 99cd3e7
simplified diagonal add
spinkney c2120e0
using object reference
spinkney 882e177
Merge commit '9be1788b0848360557c84cb50d2fd9d8b7eddcfe' into HEAD
yashikno 1b62d5e
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 90b95d8
add reverse mode differentiation
spinkney fa74e62
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney 53544c0
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 30fdbc2
fixed typo
spinkney d4f400f
add whitespace
spinkney cdebea9
make lines <= 80 char
spinkney e9f25e8
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 2467a87
one more try at <= 80 chars
spinkney ee7f8ce
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 351e0b0
again
spinkney 9e6e692
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 113efb3
keep name of input the same
spinkney 810b357
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney 29dabbd
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot bf572d6
fixed merge conflict
spinkney e1ba5c2
fixed header
spinkney 454a50f
more header fix
spinkney 4af6787
:(
spinkney 9f71335
cleanup
spinkney 6378410
more cleanup
spinkney 5866d88
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 27c31ed
fix reverse_pass_callback
spinkney e2145be
fix merge
spinkney cc21e24
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot e9365fa
Added tests for jittered function
spinkney 4aa0c9a
Merge commit 'd1a1d7e8d2e43ac6aef9ac3708841a882919b8d3' into HEAD
yashikno 6adb8ac
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot b1d7c4f
Update stan/math/rev/fun/generalized_inverse.hpp
spinkney f1efc6c
Update stan/math/prim/fun/generalized_inverse.hpp
spinkney d2ef3ce
fixed derivative
spinkney ace0138
Merge commit '7f3792baa9e91438e79a2cf6594a38d105c9b24e' into HEAD
yashikno 2f32b8d
fixed doc and include
spinkney ee29e91
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot d93620e
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney 88a8262
changed rev template from EigMat to VarMat
spinkney 8d4e39c
incorporating Steve's rev compile fixes
spinkney 709f1df
cleanup
spinkney 5f8f09b
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 483d527
val to val_op for bug in Eigen's CWiseUnaryView
spinkney 2c349df
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 873c1f3
more _op changes
spinkney e3f14c2
flip rows/cols inline
spinkney f56b9c5
small fix remove n, m using .rows()/.cols()
spinkney e768431
small fix
spinkney 2b3ab6f
more fixes
spinkney 76b5536
more fixes
spinkney 2e3e69c
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot a118eaa
more cleanup
spinkney 149c8f3
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney 9a9be26
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot a37536d
fixed merge conflict
spinkney 1ca34c0
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney 6b136cd
comment out equal tests
spinkney 27b688a
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 29d536e
test
spinkney e7af4fc
fix
spinkney 9e0fef2
Merge branch 'feature/ginv' of https://github.com/spinkney/math into …
spinkney b3534f5
Update generalized_inverse_test.cpp
spinkney 9c8f0b9
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 438bbf3
Finished tests!
spinkney 95e53a1
Merge commit '7946558172cf3d3fb60e7b117ad6ac909c2519ec' into HEAD
yashikno ec80ff1
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot d1c1d2b
Update doc for reverse specialization
spinkney 0a1b7e0
Merge remote-tracking branch 'origin/feature/ginv' into feature/ginv
spinkney b25eb0a
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 361d583
updates using ldlt
spinkney fd31404
Merge commit '3616f7195adc95ef8e719a2af845d61102bc9272' into HEAD
yashikno 18fb94f
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 7fe4f9c
newline for test
spinkney 866e9ea
new line for test
spinkney 1817807
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot c80f212
Removed unnecessary test
spinkney 393bcea
Merge commit '3d03131bdcbb2d33878f4117c857ac6404c7e10e' into HEAD
yashikno a8b1287
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot 20742a8
prim test for singular
spinkney File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#ifndef STAN_MATH_PRIM_FUN_GENERALIZED_INVERSE_HPP | ||
#define STAN_MATH_PRIM_FUN_GENERALIZED_INVERSE_HPP | ||
|
||
#include <stan/math/prim/meta.hpp> | ||
#include <stan/math/prim/err.hpp> | ||
#include <stan/math/prim/fun/Eigen.hpp> | ||
#include <stan/math/prim/fun/to_ref.hpp> | ||
#include <stan/math/prim/fun/inverse.hpp> | ||
|
||
namespace stan { | ||
namespace math { | ||
|
||
/** | ||
* Returns the Moore-Penrose generalized inverse of the specified matrix. | ||
* | ||
* The method is based on the Cholesky computation of the transform as specified | ||
* in | ||
* | ||
* <ul><li> Courrieu, Pierre. 2008. Fast Computation of Moore-Penrose Inverse | ||
Matrices. | ||
* <i>arXiv</i> <b>0804.4809</b> </li></ul> | ||
* | ||
* @tparam EigMat type of the matrix (must be derived from `Eigen::MatrixBase`) | ||
* | ||
* @param G specified matrix | ||
* @return Generalized inverse of the matrix (an empty matrix if the specified | ||
* matrix has size zero). | ||
*/ | ||
template <typename EigMat, require_eigen_t<EigMat>* = nullptr, | ||
require_not_vt_var<EigMat>* = nullptr> | ||
inline Eigen::Matrix<value_type_t<EigMat>, EigMat::ColsAtCompileTime, | ||
EigMat::RowsAtCompileTime> | ||
generalized_inverse(const EigMat& G) { | ||
using value_t = value_type_t<EigMat>; | ||
|
||
if (G.size() == 0) | ||
return {}; | ||
|
||
if (G.rows() == G.cols()) | ||
return inverse(G); | ||
|
||
const auto& G_ref = to_ref(G); | ||
|
||
if (G.rows() < G.cols()) { | ||
return (G_ref * G_ref.transpose()).ldlt().solve(G_ref).transpose(); | ||
} else { | ||
return (G_ref.transpose() * G_ref).ldlt().solve(G_ref.transpose()); | ||
} | ||
} | ||
|
||
} // namespace math | ||
} // namespace stan | ||
|
||
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#ifndef STAN_MATH_REV_FUN_GENERALIZED_INVERSE_HPP | ||
#define STAN_MATH_REV_FUN_GENERALIZED_INVERSE_HPP | ||
|
||
#include <stan/math/rev/core.hpp> | ||
#include <stan/math/prim/err.hpp> | ||
#include <stan/math/prim/fun/Eigen.hpp> | ||
#include <stan/math/rev/fun/inverse.hpp> | ||
|
||
namespace stan { | ||
namespace math { | ||
|
||
namespace internal { | ||
/* | ||
* Reverse mode specialization of calculating the generalized inverse of a | ||
* matrix. | ||
* <ul><li> Golub, G.H. and Pereyra, V. The Differentiation of Pseudo-Inverses | ||
* and Nonlinear Least Squares Problems Whose Variables Separate. <i>SIAM | ||
* Journal on Numerical Analysis</i>, Vol. 10, No. 2 (Apr., 1973), pp. | ||
* 413-432</li></ul> | ||
*/ | ||
template <typename T1, typename T2> | ||
inline auto generalized_inverse_lambda(T1& G_arena, T2& inv_G) { | ||
return [G_arena, inv_G]() mutable { | ||
G_arena.adj() | ||
+= -(inv_G.val_op().transpose() * inv_G.adj_op() | ||
* inv_G.val_op().transpose()) | ||
+ (-G_arena.val_op() * inv_G.val_op() | ||
+ Eigen::MatrixXd::Identity(G_arena.rows(), inv_G.cols())) | ||
* inv_G.adj_op().transpose() * inv_G.val_op() | ||
* inv_G.val_op().transpose() | ||
+ inv_G.val_op().transpose() * inv_G.val_op() | ||
* inv_G.adj_op().transpose() | ||
* (-inv_G.val_op() * G_arena.val_op() | ||
+ Eigen::MatrixXd::Identity(inv_G.rows(), G_arena.cols())); | ||
}; | ||
} | ||
} // namespace internal | ||
|
||
/* | ||
* Reverse mode specialization of calculating the generalized inverse of a | ||
* matrix. | ||
* | ||
* @param G specified matrix | ||
* @return Generalized inverse of the matrix (an empty matrix if the specified | ||
* matrix has size zero). | ||
* | ||
* @note For the derivatives of this function to exist the matrix must be | ||
* of constant rank. | ||
* Reverse mode differentiation algorithm reference: | ||
* | ||
* <ul><li> Golub, G.H. and Pereyra, V. The Differentiation of Pseudo-Inverses | ||
* and Nonlinear Least Squares Problems Whose Variables Separate. <i>SIAM | ||
* Journal on Numerical Analysis</i>, Vol. 10, No. 2 (Apr., 1973), pp. | ||
* 413-432</li></ul> | ||
* | ||
* Equation 4.12 in the paper | ||
* | ||
* See also | ||
* http://mathoverflow.net/questions/25778/analytical-formula-for-numerical-derivative-of-the-matrix-pseudo-inverse | ||
* | ||
*/ | ||
template <typename VarMat, require_rev_matrix_t<VarMat>* = nullptr> | ||
inline auto generalized_inverse(const VarMat& G) { | ||
using value_t = value_type_t<VarMat>; | ||
using ret_type = promote_var_matrix_t<VarMat, VarMat>; | ||
|
||
if (G.size() == 0) | ||
return ret_type(G); | ||
|
||
if (G.rows() == G.cols()) | ||
return ret_type(inverse(G)); | ||
|
||
if (G.rows() < G.cols()) { | ||
arena_t<VarMat> G_arena(G); | ||
arena_t<ret_type> inv_G((G_arena.val_op() * G_arena.val_op().transpose()) | ||
.ldlt() | ||
.solve(G_arena.val_op()) | ||
.transpose()); | ||
reverse_pass_callback(internal::generalized_inverse_lambda(G_arena, inv_G)); | ||
return ret_type(inv_G); | ||
} else { | ||
arena_t<VarMat> G_arena(G); | ||
arena_t<ret_type> inv_G((G_arena.val_op().transpose() * G_arena.val_op()) | ||
.ldlt() | ||
.solve(G_arena.val_op().transpose())); | ||
reverse_pass_callback(internal::generalized_inverse_lambda(G_arena, inv_G)); | ||
return ret_type(inv_G); | ||
} | ||
} | ||
|
||
} // namespace math | ||
} // namespace stan | ||
#endif | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#include <test/unit/math/test_ad.hpp> | ||
#include <vector> | ||
#include <gtest/gtest.h> | ||
|
||
TEST(mathMixMatFun, ad_tests) { | ||
using stan::test::expect_ad; | ||
using stan::test::expect_ad_matvar; | ||
|
||
auto f = [](const auto& G) { return stan::math::generalized_inverse(G); }; | ||
|
||
Eigen::MatrixXd t(0, 0); | ||
expect_ad(f, t); | ||
expect_ad_matvar(f, t); | ||
|
||
Eigen::MatrixXd u(1, 1); | ||
u << 2; | ||
expect_ad(f, u); | ||
expect_ad_matvar(f, u); | ||
|
||
Eigen::MatrixXd v(2, 3); | ||
v << 1, 3, 5, 2, 4, 6; | ||
expect_ad(f, v); | ||
expect_ad_matvar(f, v); | ||
|
||
v << 1.9, 1.3, 2.5, 0.4, 1.7, 0.1; | ||
expect_ad(f, v); | ||
expect_ad_matvar(f, v); | ||
|
||
Eigen::MatrixXd s(2, 4); | ||
s << 3.4, 2, 5, 1.2, 2, 1, 3.2, 3.1; | ||
expect_ad(f, s); | ||
expect_ad_matvar(f, s); | ||
|
||
// issues around zero require looser tolerances for hessians | ||
stan::test::ad_tolerances tols; | ||
tols.hessian_hessian_ = 2.0; | ||
tols.hessian_fvar_hessian_ = 2.0; | ||
|
||
Eigen::MatrixXd w(3, 4); | ||
w << 2, 3, 5, 7, 11, 13, 17, 19, 23, 25, 27, 29; | ||
expect_ad(tols, f, w); | ||
expect_ad_matvar(f, w); | ||
|
||
Eigen::MatrixXd z(2, 2); | ||
z << 1, 2, 5, std::numeric_limits<double>::quiet_NaN(); | ||
EXPECT_NO_THROW(stan::math::generalized_inverse(z)); | ||
|
||
// autodiff throws, so following fails (throw behavior must match to pass) | ||
|
||
Eigen::MatrixXd a(2, 2); | ||
a << 1.9, 0.3, 0.3, std::numeric_limits<double>::infinity(); | ||
expect_ad(f, a); | ||
expect_ad_matvar(f, a); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#include <stan/math/prim.hpp> | ||
#include <test/unit/util.hpp> | ||
#include <gtest/gtest.h> | ||
|
||
TEST(MathMatrixPrim, Zero) { | ||
stan::math::matrix_d m0(0, 0); | ||
stan::math::matrix_d ginv = stan::math::generalized_inverse(m0); | ||
EXPECT_EQ(0, ginv.rows()); | ||
EXPECT_EQ(0, ginv.cols()); | ||
} | ||
|
||
TEST(MathMatrixPrim, Singular) { | ||
using stan::math::generalized_inverse; | ||
|
||
stan::math::matrix_d m1(2, 3); | ||
m1 << 1, 2, 1, 2, 4, 2; | ||
|
||
stan::math::matrix_d m2 = m1 * generalized_inverse(m1) * m1; | ||
EXPECT_MATRIX_NEAR(m1, m2, 1e-9); | ||
} | ||
|
||
TEST(MathMatrixPrim, Equal1) { | ||
using stan::math::generalized_inverse; | ||
|
||
stan::math::matrix_d m1(2, 3); | ||
m1 << 1, 3, 5, 2, 4, 6; | ||
|
||
stan::math::matrix_d m2(2, 2); | ||
m2 << 1, 0, 0, 1; | ||
|
||
stan::math::matrix_d m3 = m1 * generalized_inverse(m1); | ||
EXPECT_MATRIX_NEAR(m2, m3, 1e-9); | ||
} | ||
|
||
TEST(MathMatrixPrim, Equal2) { | ||
using stan::math::generalized_inverse; | ||
|
||
stan::math::matrix_d m1(3, 2); | ||
m1 << 1, 2, 2, 4, 1, 2; | ||
|
||
stan::math::matrix_d m2(3, 3); | ||
m2 << 1.0 / 6.0, 1.0 / 3.0, 1.0 / 6.0, 1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0, | ||
1.0 / 6.0, 1.0 / 3.0, 1.0 / 6.0; | ||
|
||
stan::math::matrix_d m3 = m1 * generalized_inverse(m1); | ||
EXPECT_MATRIX_NEAR(m2, m3, 1e-9); | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.