How to memcpy into a two dimensional array in Structured Text? - structured-text

Basically I have this Problem like in C decribed here for Structured Text.
So in C I can do this to copy vector c into matrix rows a :
int a[100][100];
int c[10][10];
int i;
for(i = 0; i<10; i++)
{
memcpy(&a[i], &c[i], sizeof(c[0]));
}
How to do this in Structured Text? My analogous Approach does not work so far. (Compiler Error: to less indices for field a).
VAR
a: ARRAY[0..99,0..99] OF REAL; (*2D array*)
c : ARRAY[0..99] OF REAL; (*1D array*)
END_VAR
FOR i:=0 TO 99 DO
memcpy(ADR(a[i]), ADR(c[i]), SIZEOF(c[0]));
END_FOR

Are you trying to copy c into a?
For the a array, you need both indexes, like this:
memcpy(ADR(a[i,0]).....
Please test. I believe this is how I remember it, but not by my computer.

If I understand well, you would like to copy 1 dimension array (1x99 = 99 elements) to a 99 dimension array (99x99 = 9801 elements). You can copy the first array (1 dimension) in the first row o column (or vicerversa), the second in the second... etc.
If this is your porpouse you can try this code:
VAR
i: INT; //auxiliar
j: INT; //auxiliar
origin : ARRAY[0..9] OF REAL; //origin data
destiny: ARRAY[0..9,0..9] OF REAL; //destiny
END_VAR
FOR i := 0 TO 9 DO
FOR j := 0 TO 9 DO
//Copy the origin array to the first column, second, etc of destiny array
destiny[i,j] := origin[i];
END_FOR;
END_FOR;
I've tested it on my computer (using codesys) and it works, but I don't know if is this you are looking for...

Related

Does anyone know how to solve problems on variable length arrays?

Input Format
The first line contains two space-separated integers denoting the respective values of (the number of variable-length arrays) and (the number of queries).
Each line of the subsequent lines contains a space-separated sequence in the format k a[i]0 a[i]1 … a[i]k-1 describing the -element array located at.
Each of the subsequent lines contains two space-separated integers describing the respective values of (an index in the array ) and (an index in the array referenced by ) for a query.
Output Format-
For each pair of and values (i.e., for each query), print a single integer denoting the element located at an index of the array referenced by. There should be a total of lines of output.
Sample Input
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Sample Output
5
9
Somebody has solved this problem by -
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n,q; //n number of variable lenght arrays
// q no of queries asked
cin >>n >>q;
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j];
for (int y=0;y<j;y++)
cin>>Vectors[i][y];
}
int q1,q2;
for (int i=0;i<q;i++)
{
cin >>q1 >> q2;
cout<<Vectors[q1][q2]<<endl;
}
return 0;
}
Can somebody explain me this code? Or if anyone has a better approach to solve this problem. Then please explain it in detail.
This shouldn't be hard to understand, that code is basically initializing dynamic 2D array at run time then inserting values to the 2D array and then accessing it by giving index:
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j]; // initialzing inner array.. consider it as 2D array with n rows and j columns
for (int y=0;y<j;y++)
cin>>Vectors[i][y]; // insert element at specified index
}
cout<<Vectors[q1][q2]<<endl; // access element from 2D array
What you might want to use is a Matrix class.
Using
vector<vector<int>>
should do it.
Alternatively the snipet code should be refactored into a Matrix class with a constructor and a destructor.
The example you give present a memory leak since the allocated memory is not freed.

Matlab's Accumarray equivalent in C++

I found a solution for matlab's accumarray equivalent in c++ with armadillo here. Although the code works like it should in matlab, my problem is that is takes a lot of time. It takes approximately 2.2 seconds to run and i have to call this function around 360 times. Is there a way to optimize this code or anyother way to implement accumarray in c++ with armadillo/opencv/boost? I know python has a bitcount function with numpy which is fast and efficient but i cant find anything in c++.
Thank You
EDIT
Currently I am using the following function, as it can be seen in the link attached
Code:
colvec TestProcessing::accumarray(icolvec cf, colvec T, double nf, int p)
{
/* ******* Description *******
here cf is the matrix of indices
T is the values whose data is to be
accumulted in the output array S.
if T is not given (or is scaler)then accumarray simply converts
to calculation of histogram of the input data
nf is the the size of output Array
nf >= max(cf)
so pass the argument accordingly
p is not used in the function
********************************/
colvec S; // output Array
S.set_size(int(nf)); // preallocate the output array
for(int i = 0 ; i < (int)nf ; i++)
{
// find the indices in cf corresponding to 1 to nf
// and store in unsigned integer array q1
uvec q1 = find(cf == (i+1));
vec q ;
double sum1 = 0 ;
if(!q1.is_empty())
{
q = T.elem(q1) ; // find the elements in T having indices in q1
// make sure q1 is not empty
sum1 = arma::sum(q); // calculate the sum and store in output array
S(i) = sum1;
}
// if q1 is empty array just put 0 at that particular location
else
{
S(i) = 0 ;
}
}
return S;
}
There is a C-version of accumarray for python.weave. It probably could get ported to plain C++ with some effort.
https://github.com/ml31415/numpy-groupies/blob/master/numpy_groupies/aggregate_weave.py

Preparing a Matrix in C++ for Matlab

I have a sparse matrix P of dimension dim*dim given as a pointer through
double* P
/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(dim,dim,mxREAL);
/* get a pointer to the real data in the output matrix*/
P = mxGetPr(plhs[0]);
I do this in a mex file since I need a lot of for-loops to fill P and c++ is much faster then matlab for that.
For the moment, dim=22500 and it takes about 2 seconds for c++ to fill P (with matlab this task took 50 seconds), and about 100 seconds to normalize the matrix in matlab and again 100 Seconds to erase all zero colums in matlab. I do this with the following code in matlab:
for i=1:size(P,1)
if sum(P(i,:)) > 0
sum(P(i,:))
P(i,:)=(1/sum(P(i,:))).*P(i,:);
end
end
% clear empty rows and colunms
P(~any(P,2),:)=[];
P(:,~any(P))=[];
My question is now: Can I do this in c++ aswell? I tried to normalize P in c++ in the following way:
int i;
int j;
int sum;
int get_idx(int x, int y, int rows) {
return x +y * rows;
}
/* NORMALIZE */
for(i = 0; i <dim; i++) {
sum=0;
for(j=0; j<dim;j++) {
sum = sum + P[get_idx(i,j,dim)];
}
if(sum > 0) {
for(j=0; j<dim;j++) {
P[get_idx(i,j,p_rows)]=P[get_idx(i,j,dim)]*(1/sum);
}
}
}
But for some reason this code does not seem to change P, and also this takes about 85 seconds in c++. Is there a faster way that also works? Also, is it possible to clear empty rows and columns?
Why C++?
Clear the empty rows/columns before normalization - you don't need to normalize empty entries.
Vectorize the normalization:
s = sum(P, 2);
valid = s > 0;
P( valid,: ) = bsxfun(#rdivide, P(valid,:), s(valid) );
Ta-da!
bsxfun is so much fun!
Update: Regarding the reduction of rows/columns.
After a short investigation I think there is a ~x3 speed factor to gain:
Consider these three options:
P( ~any(P,2), :) = []; P( :, ~any(P,1) ) = [];
P( :, ~any(P,1) ) = []; P( ~any(P,2), :) = [];
P = P( any(P,2), any(P,1) );
Test these three alternatives and you'll see that the third one is ~x3 faster, while the first is slight (but consistently) slower than the second.
Why?
If you recall, Matlab stores matices in memory in a column-first fashion therefore eliminating columns before rows saves some copying and re-allocation of memory.
Yet, the first and second alternatives copy and reallocate memory twice: once for rows and once for columns, while the third alternative messes with the memory only once!

Double buffer vs double array c++

I was asked to create a matrix with 5 rows and unknown column.
And my boss want me to use a 1 dimensional buffer. concatenated by 5 rows buffer.
I don't get what is that mean, can some one provide me a simple example please!
With array I can do
double[][] arr = new double[5][someNumber];
But he says then the size would be limited.
So I don't know what he means by using a DOUBLE buffer, I am not very good #C++
Thank you very much, an example would be nice!
For R rows and C columns declare double arr[R * C], and arr[i * C + j] is the element at cell [i, j].
This generalizes to arbitrary dimensions.
Flattening out an array like that can be a very useful optimization, especially when you use dynamic arrays such as std::vector, where you can get a single dynamic array rather than one for each row.
Sounds like you're saying
double *arr[5];
for(unsigned int x = 0; x < 5; ++x)
{
arr[x] = new double[someNumber];
}
Since, you know that you have 5 for sure, and an unknown part my assumption is this is how you're referring to it.

Mapping array back to an existing Eigen matrix

I want to map an array of double to an existing MatrixXd structure. So far I've managed to map the Eigen matrix to a simple array, but I can't find the way to do it back.
void foo(MatrixXd matrix, int n){
double arrayd = new double[n*n];
// map the input matrix to an array
Map<MatrixXd>(arrayd, n, n) = matrix;
//do something with the array
.......
// map array back to the existing matrix
}
I'm not sure what you want, but I'll try to explain.
You're mixing double and float in your code (a MatrixXf is a matrix where every entry is a float). I'll assume for the moment that this was unintentional amd that you want to use double everywhere; see below for if this was really your intention.
The instruction Map<MatrixXd>(arrayd, n, n) = matrix copies the entries of matrix into arrayd. It is equivalent to the loop
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
arrayd[i + j*n] = matrix(i, j);
To copy the entries of arrayd into matrix, you would use the inverse assignment: matrix = Map<MatrixXd>(arrayd, n, n).
However, usually the following technique is more useful:
void foo(MatrixXd matrix, int n) {
double* arrayd = matrix.data();
// do something with the array
}
Now arrayd points to the entries in the matrix and you can process it as any C++ array. The data is shared between matrix and arrayd, so you do not have to copy anything back at the end. Incidentally, you do not need to pass n to the function foo(), because it is stored in the matrix; use matrix.rows() and matrix.cols() to query its value.
If you do want to copy a MatrixXf to an array of doubles, then you need to include the cast explicitly. The syntax in Eigen for this is: Map<MatrixXd>(arrayd, n, n) = matrix.cast<double>() .
You do not need to do any reverse operation.
When using Eigen::Map you are mapping a raw array to an Eigen class.
This means that you can now read or write it using Eighen functions.
In case that you modify the mapped array the changes are already there. You can simply access the original array.
float buffer[16]; //a raw array of float
//let's map the array using an Eigen matrix
Eigen::Map<Eigen::Matrix4f> eigenMatrix(buffer);
//do something on the matrix
eigenMatrix = Eigen::Matrix4f::Identity();
//now buffer will contain the following values
//buffer = [1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1]