Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@t4c1
Created November 13, 2019 09:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t4c1/2d766bb2076006bc0a9a448842055a4a to your computer and use it in GitHub Desktop.
Save t4c1/2d766bb2076006bc0a9a448842055a4a to your computer and use it in GitHub Desktop.
Eigendecomposition times and errors
//#include <stan/math.hpp>
#include <stan/math/prim/mat/fun/symmetric_eigensolver.hpp>
#include <chrono>
#include <cstdio>
using namespace std;
using namespace Eigen;
using namespace stan::math;
using Scalar = double;
void eigendecomposition_test(const vector<int>& sizes, int repeats = 1) {
for (int size : sizes) {
int multi_run = std::max(1, static_cast<int>(std::pow(500./size,3)));
for (int i = 0; i < repeats; i++) {
Matrix<Scalar,Dynamic,Dynamic> a = Matrix<Scalar,Dynamic,Dynamic>::Random(size, size);
Matrix<Scalar,Dynamic,Dynamic> packed(size,size);
Matrix<Scalar,Dynamic,Dynamic> rnd = Matrix<Scalar,Dynamic,Dynamic>::Random(size, size);
Matrix<Scalar,Dynamic,Dynamic> vecs(size,size);
Matrix<Scalar,Dynamic,1> vals(size);
a += a.transpose().eval();
auto start = std::chrono::steady_clock::now();
Tridiagonalization<Matrix<Scalar, Dynamic, Dynamic>> tri;
for(int j=0;j<multi_run;j++) {
tri.compute(a);
packed = tri.packedMatrix();
}
int eigen_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
start = std::chrono::steady_clock::now();
for(int j=0;j<multi_run;j++) {
stan::math::internal::block_householder_tridiag(a, packed);
}
int cpu_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
Eigen::Matrix<Scalar,Dynamic,1> diagonal = packed.diagonal();
Eigen::Matrix<Scalar,Dynamic,1> subdiagonal = packed.diagonal(1);
start = std::chrono::steady_clock::now();
for(int j=0;j<multi_run;j++) {
stan::math::internal::tridiagonal_eigensolver(diagonal, subdiagonal, vals, vecs);
}
int tri_solve_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
start = std::chrono::steady_clock::now();
for(int j=0;j<multi_run;j++) {
Eigen::internal::computeFromTridiagonal_impl(diagonal, subdiagonal, 30, true, vecs);
}
int eigen_tri_solve_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
start = std::chrono::steady_clock::now();
for(int j=0;j<multi_run;j++) {
rnd = tri.matrixQ() /* * rnd*/;
}
int eigen_apply_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
start = std::chrono::steady_clock::now();
for(int j=0;j<multi_run;j++) {
stan::math::internal::block_apply_packed_Q(packed, rnd);
}
int cpu_apply_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
double multi_run_dbl = multi_run;
printf("%d, %lf, %lf, %lf, %lf, %lf, %lf\n", size,
eigen_time / multi_run_dbl,
cpu_time / multi_run_dbl,
eigen_apply_time / multi_run_dbl,
cpu_apply_time / multi_run_dbl,
eigen_tri_solve_time / multi_run_dbl,
tri_solve_time / multi_run_dbl);
}
}
}
int main() {
printf("size, Eigen tri time[ms], My tri time[ms], Eigen apply time[ms], My apply time[ms], Eigen tri solve time[ms], My tri solve time[ms]\n");
eigendecomposition_test({100,200,500,1000,2000,3000,4000},10);
// eigendecomposition_test({100,200,500,1000},3);
// eigendecomposition_test({4000},5);
}
//#include <stan/math.hpp>
#include <stan/math/prim/mat/fun/symmetric_eigensolver.hpp>
#include <chrono>
#include <cstdio>
using namespace std;
using namespace Eigen;
using namespace stan::math;
using Scalar = double;
double residual(const Matrix<Scalar,Dynamic,Dynamic>& a, const Matrix<Scalar,Dynamic,1>& eigenvals, const Matrix<Scalar,Dynamic,Dynamic>& eigenvecs) {
return (a * eigenvecs - eigenvecs * eigenvals.asDiagonal()).array().abs().colwise().sum().maxCoeff();
}
double ortho_loss(const Matrix<Scalar,Dynamic,Dynamic>& eigenvecs) {
return (eigenvecs.transpose() * eigenvecs - Matrix<Scalar,Dynamic,Dynamic>::Identity(eigenvecs.rows(), eigenvecs.rows())).array().abs().maxCoeff();
}
void eigendecomposition_test(const vector<int>& sizes, int repeats = 1) {
for (int size : sizes) {
for (int i = 0; i < repeats; i++) {
Matrix<Scalar,Dynamic,Dynamic> a = Matrix<Scalar,Dynamic,Dynamic>::Random(size, size);
Matrix<Scalar,Dynamic,Dynamic> vecs(size,size);
Matrix<Scalar,Dynamic,1> vals(size);
a += a.transpose().eval();
auto start = std::chrono::steady_clock::now();
SelfAdjointEigenSolver <Matrix<Scalar,Dynamic,Dynamic>> slv(a);
vals = slv.eigenvalues();
vecs = slv.eigenvectors();
int eigen_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
double eigen_residual = residual(a, vals, vecs);
double eigen_ortho_loss = ortho_loss(vecs);
start = std::chrono::steady_clock::now();
selfadjoint_eigensolver(a, vals, vecs);
int cpu_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();
double cpu_residual = residual(a, vals, vecs);
double cpu_ortho_loss = ortho_loss(vecs);
printf("%d, %d, %d, %e, %e, %e, %e\n", size, eigen_time, cpu_time, eigen_residual, cpu_residual, eigen_ortho_loss, cpu_ortho_loss);
}
}
}
int main() {
printf("tri, tri_eig, size, Eigen time[ms], My time[ms], Eigen max residual, My max residual, Eigen orthogonality loss, My orthogonality loss\n");
eigendecomposition_test({100,200,500,1000,2000,3000,4000},10);
// eigendecomposition_test({4000},5);
}
size Eigen time[ms] My time[ms] Eigen max residual My max residual Eigen orthogonality loss My orthogonality loss
100 2 5 6.818920e-013 5.314460e-012 6.661338e-015 7.602619e-013
100 2 5 9.252044e-013 8.690389e-012 7.105427e-015 1.789992e-013
100 2 5 5.749197e-013 1.908592e-011 3.774758e-015 5.314508e-013
100 2 5 4.990088e-013 1.813637e-011 3.774758e-015 6.852158e-013
100 2 5 6.881162e-013 2.791475e-012 6.328271e-015 5.323606e-014
100 2 5 8.834582e-013 4.462677e-012 7.549517e-015 5.007288e-013
100 2 5 6.290177e-013 7.048008e-013 4.884981e-015 4.222785e-013
100 2 5 9.213463e-013 1.710815e-012 6.217249e-015 5.847258e-013
100 2 5 1.672204e-012 3.455406e-012 9.769963e-015 6.822678e-014
100 2 5 1.233669e-012 6.547726e-012 9.547918e-015 3.969091e-013
200 14 21 7.005105e-012 1.341316e-011 2.908784e-014 5.664414e-013
200 14 22 2.602214e-012 2.896245e-011 1.176836e-014 6.532922e-012
200 15 21 3.358643e-012 1.824219e-011 1.620926e-014 1.133957e-012
200 15 22 7.906068e-012 1.251340e-011 2.886580e-014 2.067986e-012
200 15 22 3.151943e-012 7.617449e-010 1.310063e-014 7.936718e-011
200 15 22 2.607647e-012 1.415042e-010 8.881784e-015 1.740262e-012
200 15 22 3.583077e-012 2.839045e-010 1.398881e-014 2.043626e-011
200 15 21 3.186494e-012 3.099325e-012 8.659740e-015 3.017276e-013
200 14 21 6.357683e-012 2.392043e-011 2.220446e-014 2.014488e-012
200 14 21 2.964734e-012 1.807434e-010 9.769963e-015 1.213874e-012
500 195 162 4.429976e-011 3.952968e-010 5.573320e-014 4.153715e-012
500 233 180 2.024522e-011 4.472665e-009 2.842171e-014 9.664480e-011
500 206 165 2.453048e-011 1.727767e-010 3.330669e-014 2.481896e-012
500 211 161 3.358919e-011 5.344915e-010 4.840572e-014 3.020749e-011
500 194 162 3.650308e-011 2.101175e-010 5.195844e-014 8.425208e-012
500 199 166 3.749973e-011 2.921300e-010 5.662137e-014 6.015352e-012
500 196 161 3.812880e-011 1.416366e-010 5.617729e-014 1.950664e-012
500 196 159 2.893308e-011 1.811599e-010 4.884981e-014 9.040180e-012
500 194 163 4.258553e-011 2.516204e-009 6.417089e-014 7.136103e-011
500 201 167 3.920186e-011 9.936800e-011 6.172840e-014 9.327369e-012
1000 1920 868 1.530625e-010 8.056848e-010 1.172396e-013 8.472943e-011
1000 1775 851 1.659103e-010 5.290762e-009 1.192380e-013 1.465878e-009
1000 1722 852 1.414689e-010 1.973531e-009 1.181277e-013 3.472638e-011
1000 1763 868 1.984829e-010 4.290217e-010 1.465494e-013 6.282030e-012
1000 1721 817 1.666918e-010 3.637880e-010 1.274536e-013 1.138598e-011
1000 1705 847 1.727811e-010 2.028511e-009 1.396661e-013 1.299403e-010
1000 1731 846 1.494562e-010 2.793763e-009 1.265654e-013 3.056329e-010
1000 1752 864 1.889119e-010 2.004108e-009 1.469935e-013 1.039889e-011
1000 1786 891 1.358708e-010 1.240218e-009 1.061373e-013 2.627206e-011
1000 1823 892 1.305466e-010 1.134354e-009 1.008083e-013 1.534053e-011
2000 16610 5664 5.543490e-010 3.198120e-009 2.069456e-013 5.420929e-011
2000 16241 5403 5.704461e-010 2.451249e-008 2.313705e-013 2.511754e-010
2000 16257 5425 8.126035e-010 2.046374e-008 3.248513e-013 6.732271e-010
2000 16165 5399 6.384453e-010 2.956349e-009 2.366995e-013 1.166049e-010
2000 15893 5432 5.140466e-010 3.178848e-007 1.987299e-013 4.620708e-008
2000 15935 5403 6.906517e-010 6.545977e-009 2.453593e-013 4.990502e-011
2000 15870 5626 4.847227e-010 1.267172e-008 1.905143e-013 1.282693e-010
2000 16038 5479 6.982244e-010 1.812587e-008 2.671197e-013 4.005840e-010
2000 15947 5531 6.491102e-010 3.503245e-009 2.517986e-013 2.359668e-010
2000 15851 5389 6.039694e-010 4.595018e-008 2.229328e-013 1.100552e-009
3000 53302 16579 1.845291e-009 1.077648e-007 4.711787e-013 1.764384e-008
3000 53181 16375 1.245045e-009 6.040126e-009 3.093081e-013 1.209129e-010
3000 53074 16558 1.484284e-009 8.109250e-008 3.781420e-013 8.387357e-009
3000 53155 16354 1.251405e-009 2.176914e-008 3.193001e-013 1.011060e-010
3000 53051 16679 1.629610e-009 5.590204e-009 4.363176e-013 2.802948e-010
3000 53211 17361 1.280464e-009 3.149178e-008 3.310685e-013 3.183082e-010
3000 53541 16436 1.703448e-009 2.698896e-008 4.476419e-013 1.959992e-009
3000 55947 16991 1.268775e-009 9.390530e-008 3.326228e-013 1.054301e-009
3000 53928 16510 1.229023e-009 4.918773e-008 3.026468e-013 4.830789e-010
3000 53999 16606 1.468178e-009 2.778927e-008 3.730349e-013 4.828028e-010
4000 126141 36679 2.579591e-009 4.464430e-008 5.184742e-013 3.519300e-009
4000 124552 36959 2.044163e-009 9.993964e-007 4.205525e-013 6.857670e-009
4000 124456 36592 2.095581e-009 7.111562e-009 4.227729e-013 2.413619e-010
4000 124461 36998 2.073411e-009 1.900777e-008 4.034550e-013 7.907005e-010
4000 124774 36514 2.644201e-009 2.657160e-007 5.186962e-013 1.876844e-009
4000 124400 36594 2.597082e-009 3.350777e-008 5.075940e-013 3.099531e-009
4000 124605 36459 2.711672e-009 1.167237e-007 5.262457e-013 1.638998e-009
4000 124862 36540 2.032853e-009 4.088616e-007 4.176659e-013 1.483002e-008
4000 124247 36983 2.245084e-009 1.644776e-007 4.520828e-013 9.657949e-010
4000 124419 36427 2.406090e-009 8.196682e-008 4.778400e-013 1.305511e-009
size Eigen tri time[ms] My tri time[ms] Eigen apply time[ms] My apply time[ms] Eigen tri solve time[ms] My tri solve time[ms]
100 0.296000 0.552000 0.392000 0.520000 0.016000 2.320000
100 0.304000 0.536000 0.376000 0.488000 0.016000 2.272000
100 0.296000 0.520000 0.368000 0.480000 0.016000 2.288000
100 0.296000 0.480000 0.360000 0.464000 0.016000 2.272000
100 0.296000 0.488000 0.360000 0.464000 0.016000 2.256000
100 0.296000 0.488000 0.360000 0.464000 0.016000 2.296000
100 0.320000 0.480000 0.360000 0.456000 0.016000 2.304000
100 0.296000 0.472000 0.368000 0.464000 0.016000 2.304000
100 0.304000 0.472000 0.360000 0.472000 0.016000 2.272000
100 0.296000 0.472000 0.352000 0.464000 0.016000 2.304000
200 2.066667 2.400000 1.666667 2.533333 0.666667 8.333333
200 2.066667 2.533333 1.733333 2.466667 0.666667 8.266667
200 2.000000 2.466667 1.666667 2.533333 0.666667 8.533333
200 2.200000 2.466667 1.666667 2.466667 0.666667 8.333333
200 2.200000 2.466667 1.666667 2.466667 0.666667 8.133333
200 2.133333 2.400000 1.666667 2.466667 0.666667 8.133333
200 2.133333 2.466667 1.666667 2.466667 0.666667 8.266667
200 2.000000 2.400000 1.666667 2.533333 0.666667 8.066667
200 2.000000 2.400000 1.666667 2.466667 0.666667 8.000000
200 2.066667 2.333333 1.666667 2.466667 0.666667 8.266667
500 30.000000 28.000000 18.000000 27.000000 125.000000 48.000000
500 31.000000 28.000000 18.000000 27.000000 129.000000 50.000000
500 30.000000 29.000000 18.000000 27.000000 126.000000 49.000000
500 30.000000 28.000000 18.000000 27.000000 127.000000 50.000000
500 31.000000 28.000000 18.000000 27.000000 128.000000 48.000000
500 30.000000 28.000000 18.000000 27.000000 126.000000 49.000000
500 32.000000 31.000000 19.000000 27.000000 128.000000 50.000000
500 30.000000 28.000000 19.000000 27.000000 127.000000 50.000000
500 33.000000 28.000000 18.000000 27.000000 126.000000 49.000000
500 30.000000 28.000000 19.000000 27.000000 127.000000 50.000000
1000 237.000000 220.000000 132.000000 193.000000 1094.000000 194.000000
1000 242.000000 220.000000 133.000000 194.000000 1075.000000 193.000000
1000 247.000000 221.000000 131.000000 193.000000 1073.000000 196.000000
1000 246.000000 219.000000 132.000000 192.000000 1066.000000 191.000000
1000 243.000000 223.000000 138.000000 200.000000 1083.000000 195.000000
1000 260.000000 236.000000 137.000000 199.000000 1172.000000 196.000000
1000 271.000000 235.000000 133.000000 190.000000 1074.000000 198.000000
1000 241.000000 221.000000 131.000000 191.000000 1071.000000 190.000000
1000 247.000000 221.000000 140.000000 191.000000 1071.000000 193.000000
1000 248.000000 219.000000 131.000000 190.000000 1074.000000 190.000000
2000 2605.000000 1973.000000 996.000000 1437.000000 9318.000000 775.000000
2000 2633.000000 1935.000000 999.000000 1438.000000 9371.000000 768.000000
2000 2589.000000 1947.000000 993.000000 1434.000000 9308.000000 775.000000
2000 2575.000000 1943.000000 996.000000 1434.000000 9353.000000 765.000000
2000 2596.000000 1948.000000 1000.000000 1445.000000 9258.000000 768.000000
2000 2585.000000 1943.000000 998.000000 1444.000000 9260.000000 775.000000
2000 2571.000000 1946.000000 998.000000 1432.000000 9268.000000 771.000000
2000 2587.000000 1947.000000 997.000000 1440.000000 9275.000000 766.000000
2000 2561.000000 1942.000000 999.000000 1439.000000 9219.000000 773.000000
2000 2591.000000 1955.000000 993.000000 1435.000000 9282.000000 775.000000
3000 8740.000000 6438.000000 3336.000000 4782.000000 31750.000000 1741.000000
3000 8780.000000 6416.000000 3318.000000 4764.000000 32048.000000 1750.000000
3000 9070.000000 6450.000000 3325.000000 4786.000000 31546.000000 1755.000000
3000 8738.000000 6450.000000 3307.000000 4767.000000 31773.000000 1753.000000
3000 8686.000000 6471.000000 3308.000000 4760.000000 31159.000000 1744.000000
3000 8685.000000 6455.000000 3312.000000 4764.000000 30943.000000 1741.000000
3000 8731.000000 6450.000000 3486.000000 4764.000000 31379.000000 1752.000000
3000 8791.000000 6448.000000 3311.000000 4755.000000 31368.000000 1753.000000
3000 8780.000000 6537.000000 3296.000000 4762.000000 31469.000000 1744.000000
3000 8751.000000 6462.000000 3324.000000 4773.000000 31317.000000 1742.000000
4000 20377.000000 15156.000000 7892.000000 11401.000000 74726.000000 3108.000000
4000 20483.000000 15262.000000 7977.000000 11231.000000 77612.000000 3109.000000
4000 20502.000000 15212.000000 7884.000000 11213.000000 74467.000000 3121.000000
4000 20449.000000 15923.000000 7895.000000 11192.000000 75900.000000 3145.000000
4000 20603.000000 15225.000000 7920.000000 11219.000000 73681.000000 3124.000000
4000 20456.000000 15182.000000 7889.000000 11263.000000 75245.000000 3135.000000
4000 20365.000000 15302.000000 7932.000000 11196.000000 74509.000000 3206.000000
4000 20400.000000 15182.000000 7893.000000 11188.000000 74528.000000 3131.000000
4000 20407.000000 15212.000000 7830.000000 11120.000000 73189.000000 3147.000000
4000 20725.000000 15193.000000 7911.000000 11183.000000 74153.000000 3142.000000
import pandas, numpy
import matplotlib.pyplot as plt
data = pandas.read_csv("parts_times.csv",sep = ", ")
size = numpy.array(data["size"])
data2 = pandas.read_csv("eigendecomposition_speed_precision.csv",sep = ", ")
size2 = data2["size"]
plt.plot([0, size[-1]], [1,1])
plt.plot(size, data["Eigen tri time[ms]"] / data["My tri time[ms]"], "o", label="tridiagonalization")
plt.plot(size, data["Eigen apply time[ms]"] / data["My apply time[ms]"], "o", label="Multiply w Q / coonstruct Q")
plt.plot(size, data["Eigen tri solve time[ms]"] / data["My tri solve time[ms]"], "o", label="MRRR / QR iter")
plt.plot(size2, data2["Eigen time[ms]"] / data2["My time[ms]"], "o", label="whole algorithm combined")
plt.xlabel("size")
plt.ylabel("speedup")
plt.title("Speedup")
plt.legend()
plt.show()
for col in ("Eigen max residual", "My max residual", "Eigen orthogonality loss", "My orthogonality loss"):
plt.plot(size2, data2[col], "o", label=col)
plt.xlabel("size")
plt.ylabel("error")
plt.title("Errors")
plt.semilogy()
plt.legend()
plt.show()
@t4c1
Copy link
Author

t4c1 commented Nov 13, 2019

speedup
errors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment