I am using the following struct in my project and the problem occurs in the second constructor. (I am using Visual Studio 2019.)
struct optimal_subspace {
vector<Eigen::VectorXd> span;
//empty constructor
optimal_subspace() {}
//constructor taking a pointset, the cluster number i and the size of subspaces q
//used for the k-means subspace algorithm on the whole pointset
optimal_subspace(vector<point>& pointset, int i, int q) {
//declare a vector to contain the span
vector<Eigen::VectorXd> subspace_span;
//declare integers n,d to save the dimensions of the current data matrix
int n, d;
//declare integer r to save the minimum of n and d
int r;
//using the constructor of the struct subspacematrix to get the data matrix of cluster i, the cluster mean is already subtracted
subspacematrix sm(pointset, i);
Eigen::MatrixXd m = sm.matrix;
//save the dimensions of m
n = m.rows();
d = m.cols();
//determine min(n,d)
r = min(n, d);
//check if the cluster contains points
if (sm.status == true) {
//use either Jacobi or BDCSVD according to the size of m, declare v to save V from the SVD D = U E V^T or thin SVD
//Jacobi better for matrices smaller than 16x16
Eigen::MatrixXd v;
//if r < q compute the Full decomposition as otherwise there are not enough singular vectors to obtain a q-dimensional subspace
//else compute the thin decomposition
clock_t start = clock();
if (n < 16 & d < 16) {
Eigen::JacobiSVD<Eigen::MatrixXd> svd(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
v = svd.matrixV();
}
else {
Eigen::BDCSVD<Eigen::MatrixXd> svd(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
v = svd.matrixV();
}
clock_t stop = clock();
svd_time += (double) (stop - start) / CLOCKS_PER_SEC;
for (int j = 0; j < min(q, r); j++) {
//V is of the form dxr, so, we take the r columns
subspace_span.push_back(v.col(j));
//currentsubspace.push_back(v.col(j) + mean);
}
//if r < q, we fill the subspaces by taking the coordinates of random points outside the cluster
if (min(q, r) < q) {
vector<int> non_cluster_indices = opp_ind(sm.cluster_indices, pointset.size());
uniform_int_distribution<int> uniform_dist(0, non_cluster_indices.size());
//pick randomly a point outside the cluster and add it
for (int j = min(q, r); j < q; j++) {
Eigen::VectorXd non_cluster_vector = pointset[non_cluster_indices[uniform_dist(mt)]].getcoord();
subspace_span.push_back(non_cluster_vector);
}
//orthonormalize the span
stableGramSchmidt(subspace_span, min(q, r));
}
if (subspace_span.size() == 0) cout << "error: empty subspace added" << endl;
}
span = subspace_span;
}
//constructor taking a pointset, the cluster number i and the size of subspaces q and a vector of indices representing a sample
//used for sampling k-means
optimal_subspace(vector<point>& pointset, int i, int q, vector<int> indices) {
//declare a vector to contain the span
vector<Eigen::VectorXd> subspace_span;
//declare integers n,d to save the dimensions of the current data matrix
int n, d;
//declare integer r to save the minimum of n and d
int r;
//using the constructor of the struct subspacematrix to get the data matrix of cluster i, the cluster mean is already subtracted
subspacematrix sm(pointset, indices, i);
Eigen::MatrixXd m = sm.matrix;
//save the dimensions of m
n = m.rows();
d = m.cols();
//check if the cluster contains points
if (sm.status == true) {
//use either Jacobi or BDCSVD according to the size of m, declare v to save V from the SVD D = U E V^T or thin SVD
//Jacobi better for matrices smaller than 16x16
Eigen::MatrixXd v;
//if r < q compute the Full decomposition as otherwise there are not enough singular vectors to obtain a q-dimensional subspace
//else compute the thin decomposition
clock_t start = clock();
if (n < 16 & d < 16) {
Eigen::JacobiSVD<Eigen::MatrixXd> svd(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
v = svd.matrixV();
}
else {
//ofstream file("problematicmatrix.txt", ofstream::trunc);
//file << sm.matrix.format(CommaInitFmt) << endl;
//file.close();
//Eigen::MatrixXd matrix = load_csv<Eigen::MatrixXd>("problematicmatrix.txt");
Eigen::BDCSVD<Eigen::MatrixXd> svd(sm.matrix, Eigen::ComputeThinU | Eigen::ComputeThinV);
v = svd.matrixV();
}
clock_t stop = clock();
svd_time += (double) (stop - start) / CLOCKS_PER_SEC;
int v_cols = v.cols();
int fill_up_index = min(q, v_cols);
for (int j = 0; j < fill_up_index; j++) {
subspace_span.push_back(v.col(j));
}
//if we don't have enough columns, we fill the subspaces by taking the coordinates of random points outside the cluster
if (fill_up_index < q) {
vector<int> non_cluster_indices = opp_ind(sm.cluster_indices, indices);
uniform_int_distribution<int> uniform_dist(0, non_cluster_indices.size() - 1);
//pick randomly a point outside the cluster and add it
for (int j = fill_up_index; j < q; j++) {
Eigen::VectorXd non_cluster_vector = pointset[non_cluster_indices[uniform_dist(mt)]].getcoord();
subspace_span.push_back(non_cluster_vector);
}
//orthonormalize the span
stableGramSchmidt(subspace_span, fill_up_index);
}
if (subspace_span.size() == 0) cout << "error: empty subspace added" << endl;
}
span = subspace_span;
}
};
I get the following exception:
Unhandled exception at 0x00007FF6CB72BD3B in MAaktuell.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
and when debugging after getting it, I end up in the BDCSVD.h
.
I also run it in debug mode and got the following error message:
Assertion failed: index >= 0 && index < size(), file C:\Users\Marcel\Desktop\eigen-3.3.7\eigen-3.3.7\Eigen\src\Core\DenseCoeffsBase.h, line 180
I stored the matrix using the I0 format provided by eigen
in a txt.file as follows (and included it in the second constructor, it is commented right now):
ofstream file("problematicmatrix.txt", ofstream::trunc);
ile << sm.matrix.format(CommaInitFmt) << endl;
file.close();
and uploaded it here:
problematic matrix in a txt.file
However, I tried to compute the BDCSVD for this matrix again as follows:
Eigen::MatrixXd matrix = load_csv<Eigen::MatrixXd>("problematicmatrix.txt");
Eigen::BDCSVD<Eigen::MatrixXd> svd(matrix, Eigen::ComputeThinU | Eigen::ComputeThinV);
and then, it works. If I include saving and loading the matrix in my method, it fails again. Can anyone help me finding the error? Why do I end up in the header of BDCSVD, when debugging?
User contributions licensed under CC BY-SA 3.0