This is an example on how to use the svd method.
#include "../../Test.h"
class SVDTestCase : public Test
{
bool TestSVDDimensions() {
auto U = result[0];
auto S =
eye(U.rows(), U.columns());
S(0, 0) = result[1](0, 0);
S(1, 1) = result[1](0, 1);
auto VH = result[2];
AssertEqual((U.Transpose() * S) * VH, A);
return true;
}
bool TestSVD() {
auto U = result[0];
auto S =
eye(U.rows(), U.columns());
S(0, 0) = result[1](0, 0);
S(1, 1) = result[1](0, 1);
auto VH = result[2];
AssertEqual(U * S * VH, A);
return true;
}
bool TestPCANormalDistribution() {
size_t n_points = 1000;
auto theta = M_PI / 3.0;
Matrix<double> R = { { cos(theta), -sin(theta) }, { sin(theta), cos(theta) } };
auto X = (R *
diag(sig) * random_data +
diag(xC) *
ones(2, n_points));
for(
size_t i = 0; i < X.rows(); ++i) { row_mean(0, i) =
mean(X.GetSlice(i, i, 0, X.columns() - 1), -1)(0, 0); }
auto B = X - X_bar;
B = 1.0 / (double)sqrt(static_cast<double>(X.rows())) * B;
auto U = SVD[0].Transpose();
auto S = SVD[1];
auto VT = SVD[2];
auto newTheta =
.Transpose();
auto xStd = U *
diag(S) * newTheta;
#if USE_VIS
Plot plot1(
"PCA Example");
plot1();
plot1();
Plot plot(
"PCA Example");
auto mean1 = row_mean(0, 0);
auto mean2 = row_mean(0, 1);
xStd.GetSlice(0, 0, 0, xStd.columns() - 1).Apply([mean1](double v) { return mean1 + v; }).Transpose(),
xStd.GetSlice(1, 1, 0, xStd.columns() - 1).Apply([mean2](double v) { return mean2 + v; }).Transpose(),
"conf 1",
xStd.GetSlice(0, 0, 0, xStd.columns() - 1).Apply([mean1](double v) { return mean1 + 2.0 * v; }).Transpose(),
xStd.GetSlice(1, 1, 0, xStd.columns() - 1).Apply([mean2](double v) { return mean2 + 2.0 * v; }).Transpose(),
"conf 2",
xStd.GetSlice(0, 0, 0, xStd.columns() - 1).Apply([mean1](double v) { return mean1 + 3.0 * v; }).Transpose(),
xStd.GetSlice(1, 1, 0, xStd.columns() - 1).Apply([mean2](double v) { return mean2 + 3.0 * v; }).Transpose(),
"conf 3",
std::cout << "S:\n" << S << std::endl;
{ mean1, mean2 },
{ mean1 + U(0, 0) * S(0, 0), mean2 + U(1, 0) * S(0, 0) },
};
std::cout << "PC1:\n" << pc1 << std::endl;
Matrix<double> pc2 = { { mean1, mean2 }, { mean1 + U(0, 1) * S(0, 1), mean2 + U(1, 1) * S(0, 1) } };
std::cout << "PC2:\n" << pc2 << std::endl;
plot();
#endif
return true;
}
public:
void run() override {
TestSVD();
TestPCANormalDistribution();
}
};
int main() {
SVDTestCase().run();
return 0;
}
@ DOTS
Creates dot data.
Definition: Plot.h:16
@ LINE
Creates line data.
Definition: Plot.h:14
constexpr Matrix< T > Transpose() const
Definition: Matrix.h:256
static Matrix Normal(size_t rows, size_t columns, double mu, double sigma)
Definition: Matrix.h:171
Matrix< T > Apply(const std::function< T(T)> &fun) const
Definition: Matrix.h:375
void AddData(const Matrix< double > &x, const Matrix< double > &y, const std::string &name, DataTypes dataType=DataTypes::NONE, const char *character=nullptr)
Definition: Plot.h:182
Matrix< T > HorizontalConcat(const Matrix< T > &lhs, const Matrix< T > &rhs)
Definition: matrix_utils.h:81
Matrix< T > mean(const Matrix< T > &mat, int axis=-1)
Definition: matrix_utils.h:401
Matrix< T > diag(const Matrix< T > &in)
Definition: utils.h:135
Matrix< double > eye(size_t rows, size_t columns=0)
Matrix< double > ones(size_t rows, size_t columns=1, size_t elements=1)
Matrix< double > linspace(double start, double end, unsigned long num_elements)
std::vector< Matrix< double > > svd(const Matrix< double > &A, const size_t &k, const double epsilon=0.1e-4)
Definition: svd.h:14