I have a simple Qt (v.6.4.2) code that works fine with MinGW64 compilator (Windows 10):
#include <QCoreApplication>
#include "fftw3.h"
int main()
{
QVector<int> data = {0, 1, 0, 1, 0, 1, 0, 1}; // 2^3=8 values
//-----Start fft----- (using fftw library)
fftw_complex in[data.size()], out[data.size()];
for (int i = 0; i < data.size(); i++) {
in[i][0] = data[i];
in[i][1] = 0;
}
fftw_plan p;
p = fftw_plan_dft_1d(data.size(), in, out, FFTW_FORWARD, FFTW_ESTIMATE);
fftw_execute(p);
fftw_destroy_plan(p);
//-----End fft-----
double Amplitude;
for (int i = 0; i < data.size(); i++) {
Amplitude = sqrt( pow(out[i][0], 2) + pow(out[i][1], 2) );
qDebug() << Amplitude;
}
return 0;
}
However compilation with msvc 64-bit compilator (v 17.4.33213.308) comes out with errors:
error C2131: expression is not defined by a constant
note: the crash was caused by an undefined function or a function not declared to "constexpr"
note: see usage of "QList<int>::size"
error C2131: expression is not defined by a constant
note: the crash was caused by an undefined function or a function not declared to "constexpr"
note: see usage of "QList<int>::size"
error C3863: array type "fftw_complex['function']" is non-assignable
error C3863: array type "fftw_complex['function']" is non-assignable
error C2668: pow: ambiguous call to overloaded function
Can I somehow solve this problem, or using fftw library with msvc compilator is impossible? Other Qt projects without fftw library work fine. Project *pro file:
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
SOURCES += \
main.cpp
LIBS += D:\QtProjects\fft\lib\libfftw3-3.lib
INCLUDEPATH += D:\QtProjects\fft\lib
You're attempting to use a GNU compiler extension (Variable-Length Arrays) which allows you to define an arrays bounds with a dynamic value. This is not standard C++ and is not supported in MSVC.
The lines in question are here:
QVector<int> data = {0, 1, 0, 1, 0, 1, 0, 1}; // 2^3=8 values
//-----Start fft----- (using fftw library)
fftw_complex in[data.size()], out[data.size()];
When defining the bounds of an array the value must be a compile time constant.
Try changing the above lines to the following:
QVector<int> data = {0, 1, 0, 1, 0, 1, 0, 1}; // 2^3=8 values
//-----Start fft----- (using fftw library)
fftw_complex in[8], out[8];
If the bounds of the array aren't known until runtime you'll have to use something like a std::vector instead.
Related
UPDATE: I solved it, just increased the stack size to 0x40000000, and now my code runs perfectly. (Earlier, I thought the stack size would be sufficient because I was getting a different error before (SIGSEV), and I did not think SIGBUS was also due to stack size)
I am a beginner in C++ and I have to run my recursive code on some very large inputs.
After running, I got SIGSEV Error, and I figured out that it's probably due to low stack size.
I am using CLion and I added
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-stack_size,0x20000000")
to CMakeLists.txt
Now, when I run my code, I get SIGBUS Error (interrupted by signal 10: SIGBUS).
Does anyone know why this could happen and how to fix this?
My Code:
void dfs(int x, int y) {
if (vis[x][y]) {
return;
}
vis[x][y] = 1;
if (!useless[x][y]) {
int cnt_ok = 0;
for (int d = 0; d < 4; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
if (valid(nx, ny)) {
cnt_ok += !useless[nx][ny];
}
}
useless[x][y] = cnt_ok < 2;
}
for (int d = 0; d < 4; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
if (valid(nx, ny)) {
dfs(nx, ny);
}
}
}
This is a DFS on 2-D Grid and function valid() checks for whether the coordinates are valid or not.
dx[4] = {-1, 1, 0, 0}
dy[4] = {0, 0, 1, -1}
The dimensions of vis and useless vectors are just the dimensions of the grid.
When I run with debugger in CLion:
(Line 62 is where the void dfs(int x, int y) is written. Line 86 is where dfs(nx, ny) is written.)
Also, if it's relevant - the file is so large that my computer becomes very slow and laggy when my code is running.
I also ran this code on smaller inputs and the code works perfectly fine.
Surprisingly, if a comment out the if (!useless[x][y]) the code runs fine even on large inputs and exits normally.
(Please focus on the code itself, I am beginner in c++, and I just implement pseudo-code given in books, so my code may not align with best practices.)
Thanks!
I've read through a lot of the documentation, however if you find something which I've missed that can explain away my issue I'll be pleased. For background, I'm compiling on x86 Windows 10 in Visual Studio 2015 using the 3.2.7 Eigen Library. The 3.2.7 version is from May and while there have been releases since then, I haven't seen anything in the changelog that would indicate my issue has been solved.
The issue seems to only appear for matrices above a certain size. I don't know if this is a byproduct of something specific to my system or something inherent to Eigen.
The following code produces an access violation in both Debug and Release mode.
int mx1Rows = 255, cols = 254;
{//this has an access violation at the assignment of mx2
Eigen::MatrixXd mx1(mx1Rows, cols);
Eigen::MatrixXd mx2(mx1Rows + 1, cols);
Eigen::Block<Eigen::MatrixXd, -1, -1, false> temp = mx2.topRows(mx1Rows);
mx2 = temp.array() * mx1.array();//error
}
I believe the assignment of the coefficient-wise multiplication to be safe since the result should be aliased.
This issue becomes interesting when mx1Rows is reduced to the value 254, then the access violation doesn't appear. That's correct, the mx2 dimensions of 256 by 254 produce the problem but the dimensions 255 by 254 don't. If I increase the column size I can also get the access violation, so the problem likely has something to do with the total number of entries. The issue appears even if mx1 and mx2 are filled with values, having filled matrixes is not necessary to reproduce the issue.
Similar code that does not assign the topRows() block to temp does not produce the access violation in Release mode. I believe there is something more to this since I originally identified this issue in code that was considerably more complex and it only appeared after a certain number of loops (the matrix sizes were consistent between loops). There is so much going on in my code that I haven't been able to isolate the conditions under which the access violation only appears after a certain number of loops.
What I am curious to know is
1) Am I using Eigen in some obviously wrong way?
2) Are you able to reproduce this issue? (what is your environment particulars?)
3) Is this a bug in the Eigen library?
It's easy enough to work around this problem by assigning the block to a temporary matrix instead of a block, even if it is inefficient, so I'm not interested in hearing about that.
The problem is that temp references the coefficients held by mx2, but in the last assignment, mx2 is first resized before the expression gets evaluated. Therefore, during the actual evaluation of the expression, temp references garbage. More precisely, here is what is actually generated (in a simplified manner):
double* temp_data = mx2.data;
free(mx2.data);
mx2.data = malloc(sizeof(double)*mx1Rows*cols);
for(j=0;j<cols;++j)
for(i=0;i<mx1Rows;++i)
mx2(i,j) = temp_data[i+j*(mw1Rows+1)] * mx1(i,j);
This is called an aliasing issue.
You can workaround by evaluating the expression in a temporary:
mx2 = (temp.array() * mx1.array()).eval();
Another solution is to copy mx2.topRows(.) into a true MatrixXd holding its own memory:
MatrixXd temp = mx2.topRows(mx1Rows);
mx2 = temp.array() * mx1.array();
Yet another solution is to evaluate into temp and resize afterward:
Block<MatrixXd, -1, -1, false> temp = mx2.topRows(mx1Rows);
temp = temp.array() * mx1.array();
mx2.conservativeResize(mx1Rows,cols);
Looks like a bug that affects small dimensions as well. Remove the comment in the bug inducing line to get correct results.
Correction. As ggael's answer points out, it is aliasing. It's of the type often encountered using auto to create a temp that is later used on the same object.
#include <iostream>
#include <Eigen/Dense>
int main()
{//this has an access violation at the assignment of mx2
//const int mx1Rows = 255, cols = 254;
const int mx1Rows = 3, cols = 2;
Eigen::MatrixXd mx1(mx1Rows, cols);
int value = 0;
for (int j = 0; j < cols; j++)
for (int i = 0; i < mx1Rows; i++)
mx1(i,j)=value++;
Eigen::MatrixXd mx2(mx1Rows + 1, cols);
for (int j = 0; j < cols; j++)
for (int i = 0; i < mx1Rows+1; i++)
mx2(i,j)=value++;
Eigen::Block<Eigen::MatrixXd, -1, -1> temp = mx2.topRows(mx1Rows);
mx2 = temp.array()/*.eval().array()*/ * mx1.array();r
std::cout << mx2.array() << std::endl;
}
// with /*.eval().array()*/ uncommented
//0 30
//7 44
//16 60
// Original showing bug
//-0 -4.37045e+144
//-1.45682e+144 -5.82726e+144
//-2.91363e+144 -7.28408e+144
I am compiling a program that uses several Eigen::MatrixXd methods, and while I get no errors when compiling it, running it I get the following error:
darwin-pi2: /usr/include/Eigen/src/Core/Assign.h:498: Derived& Eigen::DenseBase<Derived>::lazyAssign(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::Matrix<double, -1, -1>; Derived = Eigen::Matrix<double, 15, 15, 0, 15, 15>]: Assertion `rows() == other.rows() && cols() == other.cols()' failed.
I guess it is something related to Eigen matrices, but I do not understand what Assertion rows() == other.rows() && cols() == other.cols()' failed means.
Because Eigen::MatrixXd has dimensions determined at runtime, the compile-time size checks are all disabled and deferred until runtime.
In this case, it looks like you're assigning from a dynamic-size matrix to a 15x15 one. Try double-checking and debugging the size of that dynamic one.
In matlab, the index of a matrix m starts from 1. But in eigen, it starts from 0. Show a simple example.
#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXd;
int main()
{
MatrixXd m(2,2);
m(0,0) = 3; // INDEX starts from 0, not 1
m(1,0) = 2.5;
m(0,1) = -1;
m(1,1) = m(1,0) + m(0,1);
std::cout << m << std::endl;
}
For more information, click the docs.
I was solving a programming problem on a site. On my machine (Visual Studio 2010) a test case gives wrong result, while gives correct result on the site. I am not sure what is the compiler of the site's judge, but I think it is something like gcc or cygwin.
THE CODE
A graph problem. The graph here is represnted as a tree. The graph is directed, and doesn't contain loops. The solution is (2 * sum of all edges - max path length from root)
// to-vertex & edge-length
vector<pair<int, int> > pr[100];
int dfs(int i) // to find max path length from root
{
int mx = 0;
for (int j = 0; j < pr[i].size(); ++j)
mx = max(mx, dfs(pr[i][j].first) + pr[i][j].second);
return mx;
}
int PowerOutage::estimateTimeOut(vector <int> from_vertex,
vector <int> to_vertex, vector <int> edge_length)
{
int tot = 0;
for (int i = 0; i < from_vertex.size(); ++i)
{
pr[from_vertex[i]].push_back(make_pair(to_vertex[i], edge_length[i]));
tot += (2 * edge_length[i]);
}
return tot - dfs(0);
}
THE TEST CASE
from_vertex {0, 0, 0, 0, 0}
to_vertex {1, 2, 3, 4, 5}
edge_length {100, 200, 300, 400, 500}
Visual Studio returns: 2493, While the site's compiler returns the correct answer: 2500.
Why the two results are different? I think there is some hidden bug (in my code) that appears in VS giving wrong answer but disapper in the other compiler. Should I determine the site's compiler and use it instead?
Despite my first(wrong) assumption, OP has found out that it was 2500 already but the test-function had the flaw after i asked him "where is 2500 printed?".
In SparseSuiteQR, all of the examples I can find use stdin or a file read to create a sparse matrix. Could someone provide a simple example of how to create one directly in C++?
Even better, in the CHOLMOD documentation, there is mention of a sparse2 function available in matlab, which behaves the same as the sparse. Can this be used in C++?
The data structures used by SuiteSparseQR (e.g. cholmod_sparse) are defined in the CHOLMOD library. You can find more information about it on the CHOLMOD documentation, which is much larger than the one from SuiteSparseQR.
I am assuming that you try to solve a linear system, see the CSparse package from Tim Davies, or boost matrix libraries which also have numeric bindings which interface umfpack and some lapack functions AFAIK...
CHOLMOD is a pretty awesome project - thanks Tim Davis :)
There is surprisingly a lot of code on GitHub that makes use of CHOLMOD, but you have to be logged into GitHub and know what you're looking for!
So, after crawling through CHOLMOD documentation and source code and then searching through GitHub for source code that uses CHOLMOD you would find out what to do.
But for most developers who want/need a quick example, here it is below.
*Note that your mileage might vary depending on how you compiled SuiteSparse.
(You might need to use the cholmod_ variant (without the l), i.e. not cholmod_l_; and use int for indexing, not long int).
// example.cpp
#include "SuiteSparseQR.hpp"
#include "SuiteSparse_config.h"
int main (int argc, char **argv)
{
cholmod_common Common, *cc;
cholmod_sparse *A;
cholmod_dense *X, *B;
// start CHOLMOD
cc = &Common;
cholmod_l_start (cc);
/* A =
[
1.1, 0.0, -0.5, 0.7
0.0, -2.0, 0.0, 0.0
0.0, 0.0, 0.9, 0.0
0.0, 0.0, 0.0, 0.6
]
*/
int m = 4; // num rows in A
int n = 4; // num cols in A
int nnz = 6; // num non-zero elements in A
int unsymmetric = 0; // A is non-symmetric: see cholmod.h > search for `stype` for more details
// In coordinate form (COO) a.k.a. triplet form (zero-based indexing)
int i[nnz] = {0, 1, 0, 2, 0, 3}; // row indices
int j[nnz] = {0, 1, 2, 2, 3, 3}; // col indices
double x[nnz] = {1.1, -2.0, -0.5, 0.9, 0.7, 0.6}; // values
// Set up the cholmod matrix in COO/triplet form
cholmod_triplet *T = cholmod_l_allocate_triplet(m, n, nnz, unsymmetric, CHOLMOD_REAL, cc);
T->nnz = nnz;
for (int ind = 0; ind < nnz; ind++)
{
((long int *) T->i)[ind] = i[ind]; // Notes:
((long int *) T->j)[ind] = j[ind]; // (1) casting necessary because these are void* (see cholmod.h)
((double *) T->x)[ind] = x[ind]; // (2) direct assignment will cause memory corruption
} // (3) long int for index pointers corresponds to usage of cholmod_l_* functions
// convert COO/triplet to CSC (compressed sparse column) format
A = (cholmod_sparse *) cholmod_l_triplet_to_sparse(T, nnz, cc);
// note: if you already know CSC format you can skip the triplet allocation and instead use cholmod_allocate_sparse
// and assign the member variables: see cholmod.h > cholmod_sparse_struct definition
// B = ones (size (A,1),1)
B = cholmod_l_ones (A->nrow, 1, A->xtype, cc);
// X = A\B
X = SuiteSparseQR <double> (A, B, cc);
// Print contents of X
printf("X = [\n");
for (int ind = 0; ind < n; ind++)
{
printf("%f\n", ((double *) X->x)[ind]);
}
printf("]\n");
fflush(stdout);
// free everything and finish CHOLMOD
cholmod_l_free_triplet (&T, cc);
cholmod_l_free_sparse (&A, cc);
cholmod_l_free_dense (&X, cc);
cholmod_l_free_dense (&B, cc);
cholmod_l_finish (cc);
return 0;
}
Supposing you have compiled SuiteSparse successfully and you have saved example.cpp in the base directory, then the following should work (on Linux):
gcc example.cpp -I./include -L./lib -lcholmod -lspqr -lsuitesparseconfig -o example
#Add SuiteSpare libraries to your `ld` search path if necessary
LD_LIBRARY_PATH=$(pwd)/lib
export LD_LIBRARY_PATH
./example
Output:
X = [
0.353535
-0.500000
1.111111
1.666667
]