Can someone be able to tell me how to convert vector to an array?
I have a function that returns a vector of double type with typical like this
std::vector<double> x_vec = LinspaceArray_DK2(0, 5.0, 0.01);
std::vector<double> y_vec = Calculate_y_vec(x_vec);
However, following GSL (GNU scientific lib) function is expecting an array as an input
gsl_spline_init (spline, x_array, y_array, x_vec.length);
Here, x_array, y_array are arrays corresponding to vectors x_vec and y_vec.
I tried following solution here (How to convert vector to array in C++) which suggest conversion like this:
std::vector<double> v;
double* a = &v[0];
But, this type of conversion did not help with gsl_spline_init which expected arrays as inputs.
Updated:
I tried to call like this:
// Convert all vector to an array
double* x_input_Array = &x_input[0];
double* y_input_Array = &y_input[0];
and then call:
gsl_spline_init (spline, *x_input_Array, *y_input_Array, iNoOfPtsIni);
I am getting this error:
error C2664: 'gsl_spline_init' : cannot convert parameter 2 from 'double' to 'const double []'
Thanks,
DK
You do not need (and should not) dereference - the function you call expects arrays, and you pass their first elements. Use
gsl_spline_init (spline, x_input_Array, y_input_Array, iNoOfPtsIni);
Related
I have a vector of doubles that I am passing to a lib https://github.com/llohse/libnpy in order to read a numpy file:
std::vector<unsigned long> shape {};
bool fortran_order;
std::vector<double> dataNpy;
const std::string path {"/home/ubuntu/template.npy"};
npy::LoadArrayFromNumpy(path, shape, fortran_order, dataNpy);
I will need to further process this data and have been instructed to use arrays since vector copy is not optimal.
So this data should be a matrix but the lib reads it as linear.
That is why I want to create a pointer to a 2D table with a given size for rows and columns like this with the data from the vector
double (*template_data)[12] = (double (*)[12]) dataNpy.data();
When I do it by explicitly putting the size, like above the compiler is ok with it, however, when I do it like the code below i get an error:
int sizeRows = 12, sizeColumns=12;
double (*template_data)[sizeRows] = (double (*)[sizeColumns]) dataNpy.data();
Cannot initialize a variable of type 'double ( * )[sizeRows]' with an rvalue of type 'double ( * )[sizeColumns]'
Could you explain to me why that is?
Function is defined as:
int strip(double *signalstnV){
.
.
return 0;
}
And main function it is called as:
main{
.
.
double signalstnV[iteration][2*range+1][3];
.
.
check = strip(signalstnV);
.
}
I wanted to use the array in next function in main after it is modified in strip function. But during compilation i am getting an error as following
sim.C: In function ‘int main(int, char**)’:
sim.C:54:26: error: cannot convert ‘double ()[151][3]’ to ‘double’ for argument ‘1’ to ‘int strip(double*)’
check = strip(signalstnV);
I am not able to understand it. Please help.
My main goal is to generate array from strip function and pass it to other functions later in code.
Also when i used this array in another function
threshold(double * signalstnV)
and using a for loop to extract some specific values, it gives error as:
invalid types ‘double[int]’ for array subscript
if (signalstnV[k][j][3] < -0.015){
..}
An ordinary single-dimensional array decays to a pointer to its first value. A multi-dimensional array decays only in its first dimension, decaying to a pointer to the initial 2nd dimension of the array.
If you wish to "super-decay" a multi-dimensional array to a pointer to its first value, then simply do that yourself:
check = strip(&signalstnV[0][0][0]);
For such cases, with more or less complicated types - use type aliases:
//double signalstnV[iteration][2*range+1][3];
using IterationValues = double[iteration];
using IterationRangesValues = IterationValues [2*range+1];
//...
then, it is obvious that calling this:
IterationRangesValues signalstnV[3];
check = strip(signalstnV);
You need this signature: strip(IterationRangesValues * matrix) or this strip(IterationRangesValues (& matrix)[3]). Of course for this last array you might use typedef too.
You might also use std::array:
using IterationValues = std::array<double, iteration>;
using IterationRangesValues = std::array<IterationValues, 2*range+1>;
//...
To pass the array by reference, one way is:
template<size_t X, size_t Y, size_t Z>
int strip( double(&strip)[X][Y][Z] )
{
}
Then you can call it with various sizes of array.
If you only need to support the one size, then remove the template line and replace X Y Z with the actual dimensions you need to support.
I am trying to manage an array of structures using vectors but keep getting an error msg.
The vector is declared in the header file as:
vector< TLE_Values, allocator<TLE_Values> > SavedSatellites;
which VS2013 is quite happy with.
The structure is defined as:
struct TLE_Values
{
string CatalogNum;
string SatelliteName;
string DateStr;
string TimeStr;
string Classification;
double DecayValue;
int ElsetNum;
double InclinationValue;
double RaanValue;
double EccentricityValue;
double ArgPerigeeValue;
double PerigeeAngle;
double AvgSpeed;
double Period;
int OrbitNum;
};
and initialised with default values by a constructor.
In the main program code, having determined the number of elements I will require ( CountItemsInFile() ), I try to expand the vector list using:
SavedSatellites.push_back(CountItemsInFile());
This however returns the following compiler error message:
error C2664:
'void std::vector<TLE_Values,std::allocator<TLE_Values>>::push_back(const TLE_Values &)' : cannot convert argument 1 from 'int' to 'TLE_Values &&'
1> Reason: cannot convert from 'int' to 'TLE_Values'
1> No constructor could take the source type, or constructor overload resolution was ambiguous.
Another thread suggested that a vector needed to be initialised with 0, which won't happen with a user defined type like this.
What am I missing? where have I gone wrong? How do I create the initial vector with my structure?
There's lots of documentation for using vectors of type (int) but not much if you're not using integers.
To expand a vector use
SavedSatellites.resize(CountItemsInFile());
If you just want reserve memory for it but keep the size of the vector untouched and ready for subsequent push_back without memory reallocation:
SavedSatellites.reserve(CountItemsInFile());
The docs are key here:
void push_back (const value_type& val);
push_back doesn't take an int, it takes a parameter of the same type your vector holds. You need to give it a TLE_Values object.
You also don't need to preemptively size the vector; you can just keep calling push_back until you're done.
I have written a C++ application and within it, I need to call a math function that was written in C. The prototype looks like:
void Jacobi_Cyclic_Method(double *eigenvalues, double *eigenvectors, double *A, int n);
My problem is that I can't seem to pass the function double * (for instance both eigenvectors and A are multi-dimensional arrays. The C++ way to pass those things seems to be
double [][size]
I have read about extern C but I don't think it applies here since I am not interfacing with an object but with source itself. How can I send that C function my multi-dimensional arrays defined as such:
double [100][100] A;
double [100][100] eigenvectors;
double [100] eigenvalues;
Trying to compile I get:
error: no matching function for call to ‘MathEngine::Jacobi_Cyclic_Method(double
[100], double [100][100], double [100][100], int)’
mathEngine.h:9: note: candidates are: static void
MathEngine::Jacobi_Cyclic_Method(double*, double*, double*, int)
Probably the problem is that your Jacobi_Cyclic_Method function requires the matrix to be in either column or row major format, where every column/row is stored consecutively in a single, one-dimensional array. E.g. for a row major matrix of size m x n, the elements in any given row are stored contiguously and the item in row i and column j would be at position i*n+j (for zero-based indices i and j). If the matrix is column-major, it would be at position i+j*m.
Using multi-dimensional arrays in C/C++ is often not what you want because something like
double A[100][100];
is not a two-dimensional array, but a single array of length 100 containing pointers to arrays of length 100. Consequently, the rows in A are not stored contiguously.
I'm assuming that your C function requires multi-dimensional arrays for some of its parameters and that the prototype is written with pointers to doubles for the array/matrix parameters where the integer parameter indicates the size of each dimension (I guess the matrices are square?). If this is the case then you can pass a pointer to the first element of each array/matrix like this:
Jacobi_Cyclic_Methods(&eigenvalues[0], &eigenvectors[0][0], &A[0][0], 100);
Your initial attempt doesn't work because the type of, for instance, eigenvectors is double[100][100] which decays to double (*)[100], not double *.
This post addresses the issue of pointers and multi-dimensional arrays.
I am a Java guy jumping into CUDA and the syntax is tripping me. I'm trying to create a matrix in the .cpp file then pass that off to the .cu file to be processed. I see examples where the CUDA function expects the 2D array to come in looking like
void handleMatrix(float* A){
// do stuff
}
when I create the matrix I'm used to doing it in code that looks like this:
int main()
{
const int row=8;
const int column=8;
int rnum;
srand(time(0));
rnum = (rand() % 100) + 1;
float table[row][column];
for(int r=0; r<row; r++){
for(int c=0; c<column;c++){
table[row][column] = (rand()%100) + 1.f;
}
cout << "\n";
}
handleMatrix(table);
return 0;
}
When I compile the code I'm getting the error
cannot convert ‘float ()[8]’ to ‘float*’ for argument ‘1’ to ‘void handleMatrix(float*)’*
Is there a different way I should be declaring the matrix or creating it?
Thanks in advance for the help.
You can do
handleMatrix(table[0]);
or, equivalently,
handleMatrix(&table[0][0]);
That's if 'handleMatrix' is host code. If it's device code, you can't allocate the buffer like that. You'll want to assemble an array in local memory, fill the entries, allocate another array in the device memory using cudaMalloc() or cudaMallocPitch(), and then copy from local to device using cudaMemcpy() or cudaMemcpy2D().
You want a pointer to an array. The syntax for declaring a pointer to an array is
void handleMatrix(float (*A)[8][8]) {
// do stuff
}
That is, when you dereference A, you get a reference to an 8 by 8 array of floats.
Even for 1D arrays, there is a distinction between pointer to array (float (*anArray)[100]) and pointer to element (float *anArray). C++ will transparently convert the former to the latter, which means that for 1D arrays (but not arrays of higher dimension) you can usually ignore the difference.
In your example, table[0] converts to a valid float* pointer to 64 consecutive float numbers. But it looks highly suspicious that handleMatrix takes a pointer meant to be an array and doesn't take any information about the dimensions of that array.
the handleMatrix() function, is this a function from you or is part of a library? If the latter you may need to create the 2-d array as a long row x col 1-d array. If the former you need to change the function to accept a 2-d array e.g. handleMatrix(float**m) and pass the dimensions of the matrix to the function;
preferably though you should use vector<> when programming in C++ then the dimensions are known by the callee.
e.g.
#include <vector>
typedef std::vector<std::vector<float > > matrix;
void handleMatrix( matrix& m ) {..}