I am new here so i am sorry if my question is a kind stupid, but, i was calculating the divisions of two large numbers and storing them in an array, like this:
int det(double M[25][25], int m)
{
/*returns large numbers*/
}
int main()
{
float y[27];
double A[25][25] = {0}, N = 26, D = -134430487042201894894174208;
y[0] = 0;
y[26] = 1;
for (int i = 0; i < N-1; i++)
{
//Reset A[][] to the original
for (int k = 0; k < N-1; k++)
{
for (int J = 0; J < N-1; J++)
{
A[k][J] = m[k][J];
}
}
//Change values of A[j][i]
for (int j = 0; j < N-1; j++)
{
A[j][i] = d[j+1];
}
y[i+1] = det(A,N-1)/D; //Here y returns only 0, 1, 1, 1, 1, ...
}
}D
So, what am i doing wrong? y array returns 0, 1, 1, 1, 1, ... , and it was supposed to not be 1
det(A,N-1) = 7958284334509567005163520
D = -134430487042201894894174208
det(A,N-1)/D = -0.05919999629259109195883585509348322869497780932400145347...
It's not 1.
Thanks!
The function det is returning an int. You are never going to get floating point values from it.
Related
I am trying to fill an array sized by [4344][20] with the contents of other array sized by [5430][20]. I wrote the following code and it has no errors. It filled the X_train correctly, but the Y_train didn't filled successfully. it remained zeros as its initialized.
my code:
void split(int fold, int array_X_set[5430][20], int array_Y_set[5430],
int X_train[4344][20], int Y_train[4344],
int X_test[1086][20], int Y_test[1086])
{
int rows = 5430;
int cols = 20;
int division = 1086;
int nTest = 0, nTrain = 0, nTest1 = 0, nTrain1 = 0;
switch (fold) {
case 1:
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
if (i < division) {
X_test[nTest][nTest1] = array_X_set[i][j];
Y_test[nTest] = array_Y_set[i];
nTest1++;
}
else {
X_train[nTrain][nTrain1] = array_X_set[i][j];
Y_train[nTrain] = array_Y_set[i];
nTrain1++;
}
}
}
break;
another condition :
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
if (i >= 1086 && i <= 2171) {
X_test[i][j] = array_X_set[i][j];
Y_test[i] = array_Y_set[i];
}
else {
X_train[i - division][j] = array_X_set[i][j];
Y_train[i - division] = array_Y_set[i];
}
}
}
you can try this code, so that you don't need extra variable like nTest, nTrain, nTest1, nTrain1.
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
if (i < division) {
X_test[i][j] = array_X_set[i][j];
Y_test[i] = array_Y_set[i];
} else {
X_train[i-division][j] = array_X_set[i][j];
Y_train[i-division] = array_Y_set[i];
}
}
}
updated:
Another condition:
if you have 10 elements in array
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
^ ^ ^ ^
you want to put index 3~6 to new array, in new array, its index would be 0~3
so for the part >=3 && <=6 would be newArr[i-3] = originalArr[i]
and if you want to put index 0~2 and 7~9 to new array, in new array, its index would be 0~2 and 3~5
so for the part <3 would be newArr[i] = originalArr[i]
the part >6 would be newArr[i-(6-3+1)] = originalArr[i], (6-3+1) means the element count between the part >=3 && <=6
Here is the code in your condition:
(>=1086 && <=2171 in test array, <1086 || >2172 in train array)
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
if (i >= 1086 && i <= 2171) {
X_test[i - 1086][j] = array_X_set[i][j];
Y_test[i - 1086] = array_Y_set[i];
}
else {
if(i<1086){
X_train[i][j] = array_X_set[i][j];
Y_train[i] = array_Y_set[i];
}else{
X_train[i - (2171-1086+1)][j] = array_X_set[i][j];
Y_train[i - (2171-1086+1)] = array_Y_set[i];
}
}
}
}
Edit: I have uploaded the vector to Drive as a text file, in case anyone want to have a look: https://drive.google.com/file/d/0B0wsPU8YebRQbDUwNFYza3ljSnc/view?usp=sharing
I'm trying to reshape my vector h into a 3D array. h contains 295788 elements. In this case height = 314, width = 314 and depth = 3.
Basically what I'm trying to do is what MATLAB does with its reshape function.
h = reshape(h, height, width, depth)
This is my attempt so far, but when I print it all I see is zeroes, which is not right. I have double checked that h contains the numbers I'm expecting.
vector<vector<vector<double> > > array3D;
int height = 314, width = 314, depth = 3;
// Set up sizes
array3D.resize(height);
for (int i = 0; i < height; ++i) {
array3D[i].resize(width);
for (int j = 0; j < width; ++j)
array3D[i][j].resize(depth);
}
for (int i = 0; i < height; i++)
{
array3D[i][0][0] = h[i];
for (int j = 0; j < width; j++)
{
array3D[i][j][0] = h[i+j];
for (int k = 0; k < depth; k++)
{
array3D[i][j][k] = h[i+j+k];
}
}
}
Printing:
for (vector<vector<vector<double>>>::const_iterator i = array3D.begin(); i != array3D.end(); ++i)
{
for (vector<vector<double>>::const_iterator j = i->begin(); j != i->end(); ++j)
{
for (vector<double>::const_iterator k = j->begin(); k != j->end(); ++k)
{
cout << *k << ' ';
}
}
}
So my question is, how do I convert my vector into a 3D array properly?
I managed to do this by using Eigen::Tensor as suggested by Henri Menke. I ended up creating an array for the initial 314x314x3 matrix, and then another one for the 300x300x3 matrix. It's neither fast nor pretty, but for now that is what I could come up with. Looks like this.
For clarification: margin is calculated further up in the code, but in this example with the 314x314x3 matrix it's margin=7. h is a vector with 295788 elements. nrh=314, nch=314 and nradii=3.
Tensor<int, 3> t(nrh, nch, nradii);
int counter = 0;
for (int k = 0; k < nradii; k++)
{
for (int col = 0; col < nch; col++)
{
for (int row = 0; row < nrh; row++)
{
t(row, col, k) = h[counter];
counter += 1;
}
}
}
int height = nrh - margin * 2;
int width = nch - margin * 2;
int depth = nradii;
Tensor<int, 3> out(height, width, depth);
int count1 = 0, count2 = 0, count3 = 0;
for (int k = 0; k < depth; k++)
{
for (int j = margin; j < nch - margin; j++)
{
for (int i = margin; i < nrh - margin; i++)
{
out(count1, count2, count3) = t(i, j, k);
count1 += 1;
}
count1 = 0;
count2 += 1;
}
count2 = 0;
count3 += 1;
}
Edit: Solution #2 with Tensor.slice()
int height = nrh - margin * 2;
int width = nch - margin * 2;
int depth = nradii;
Tensor<int, 3> tensor(height, width, depth);
DSizes<ptrdiff_t, 3> indices(margin, margin, 0);
DSizes<ptrdiff_t, 3> sizes(height, width, nradii);
tensor = t.slice(indices, sizes);
How about:
array3D[i][j][k] = h[i*(depth*width)+j*depth+k];
That may or may not be scanning the vector in the correct order.
Notice how when the index k resets the index j increments so you move on exactly one until the index j resets in which case i increments and the same. It's easy to show this calculation reads every element exactly once.
I'd normally expect a width, height then depth and you're scanning in the opposite order!
Footnote: Depending on the application is may be worthwhile to just access the vector using this approach. In general it turns out to be faster than accessing a vector of vectors of vectors. That can be relevant when dealing with massive arrays.
Actually, your the structure of your code is already ok, however, there are two mistakes:
The lines
array3D[i][0][0] = h[i];
and
array3D[i][j][0] = h[i+j];
are pointless. You are overwriting those entries later on with the line
array3D[i][j][k] = h[i+j+k];
The index calculation for h[] is wrong: You must multiply the row index by the length of a row before adding the cell index. The assignment should look like this:
array3D[i][j][k] = h[(i*width+j)*depth+k];
Otherwise, you will get the same result for (i, j, k) == (3, 2, 1) as for (i, j, k) == (1, 3, 2), which is obviously wrong. In the index calculation above, I have assumed that k is the fastest changing dimension. If that is not the order in which your data is stored in h, you need to change the positions of i, j, and k and adjust the factors accordingly.
Putting this together, your assignment loop should read:
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
for (int k = 0; k < depth; k++) {
array3D[i][j][k] = h[(i*width+j)*depth+k];
}
}
}
Slightly off-topic:
If you were using C instead of C++, you could "simply" do this:
size_t dataSize;
//Create a real 3D array with the dimensions (height, width, depth).
double (*array3D)[width][depth] = malloc(dataSize = height*sizeof(*array3D));
//Copy over the data from the file.
memcpy(array3D, h, dataSize);
//Print the array contents:
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
for (int k = 0; k < depth; k++) {
printf("%d ", array3D[i][j][k]);
}
}
}
This uses a real 3D array instead of an array of pointers to arrays of pointers to arrays of doubles (which is roughly what a vector<vector<vector<double>>> is). However, this cannot be done in C++ as C++ does not allow for array types with dynamic sizes as C does.
I have converted a piece of code to C++ using Matlab and now have them in MSVC++.
My function: myFunction gets two inputs and has one output. Following, I tried to make the inputs, a, b, and allocate the output, but I got this error: error C3861: 'emxCreate_real_T': identifier not found
The function prototype looks like this, which in essence is C = A + B:
#include "myTestFunction.h"
#include "myTestFunction_emxutil.h"
void myTestFunction(const emxArray_real_T *A, const emxArray_real_T *B,
emxArray_real_T *C)
{
int i0;
int loop_ub;
i0 = C->size[0] * C->size[1];
C->size[0] = A->size[0];
C->size[1] = A->size[1];
emxEnsureCapacity((emxArray__common *)C, i0, (int)sizeof(double));
loop_ub = A->size[0] * A->size[1];
for (i0 = 0; i0 < loop_ub; i0++) {
C->data[i0] = A->data[i0] + B->data[i0];
}
}
and here is my main function:
int main() {
double a[3][3];
double b[2][2];
double result[4][4] = {};
emxArray_real_T *inpA, *inpB, *outp;
// define input matrix
double p = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++){
a[i][j] = p;
p = p + 1;
}
}
double k = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
b[i][j] = k;
k = k + 1;
}
}
inpA = emxCreateWrapper_real_T(*a, 3, 3);
inpB = emxCreateWrapper_real_T(*b, 2, 2);
outp = emxCreateWrapper_real_T(*result, 4, 4);
//inpA = emxCreate_real_T(a, 3, 3);
//inpB = emxCreate_real_T(b, 2, 2);
//outp = emxCreate_real_T(result, 4, 4);
myTestFunction(inpA, inpB, outp);
//print result
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++)
cout << outp[i].data[j] << endl;
}
return 0;
}
How should I declare the inputs and output?
You're missing an include file. Based on the link you provided in your comment, there is probably a myTestFunction_emxAPI.h file that needs to be included.
Also, I see that the b[2][2] array that you created is being accessed beyond its bounds by the for (int i = 0; i < 3; i++)' andfor (int j = 0; j < 3; j++)` loops.
Suppose I have a point P in [0,1]*[0,1], and [0,1] is divided into m(say 200) grids. I use A[m][m] to indicate whether [a small square centred at P with length 2h] covers each grid or not. So for a point P, A[i][j] is either (increase by) 1 or 0.
Suppose I have n such points(P1,...,Pn), I want to calculate A(for each point Pi, I redo the above procedure, adding 1 or not). How can I do this efficiently(with C++) rather than writing 3 layers of for loops to check for each grid and each point(So O(nm^2))?
I tried the naive 3 for loops with C++. It takes longer time than using some of the vectorized operations(like vector<= number for comparing n numbers together, A[bool vector, bool vector] for subsetting) in R.
Since C++ is generally faster than R, is there any smart way to implement this process?
#include <Rcpp.h>
#include <cmath>
using namespace Rcpp;
// [[Rcpp::export]]
double myfun(NumericVector u, NumericVector v)
{
double n = u.size();
double A[200][200] = {0};
double pos[200];
int i = 0, j = 0, k = 0;
for (i = 0; i < 200; i++)
{
pos[i] = (double)i / 201;
}
for (k = 0; k < n; k++)
{
for (i = 0; i < 200; i++)
{
for (j = 0; j < 200; j++)
{
if ( (fabs(u[k] - pos[i]) <= h) && (fabs(v[k] - pos[j]) <=h ) )
{
A[i][j]++;
}
}
}
}
double s = 0, avg = 0;
for (i = 0; i <200; i++)
{
for (j = 0; j < 200; j++)
{
s += A[i][j];
}
}
avg = s / (200 * 200);
return (avg);
}
The two inner loops only determine index of the point in your grid. But you can compute the index directly:
int i = (int)(u[k]*200);
int j = (int)(v[k]*200);
You probably also need to check that i and j don't reach the index 200. This only happens though, when u[k] == 1.0 or v[k] == 1.0.
double n = u.size();
double A[200][200] = {0};
for (int k = 0; k < n; k++)
{
int i = (int)(u[k]*200);
int j = (int)(v[k]*200);
if (i == 200)
i = 199;
if (j == 200)
j = 199;
A[i][j]++;
}
I'm trying to develop a wordsearch which finds the word "OIE" (indicating how many times appears), based in an integer unidimensional array that saves the directions (8), but I get strange errors when I run this (and incorrect outputs).
This is the code:
int arrf[8] = {0, -1, -1, -1, 0, 1, 1, 1};
int arrc[8] = {-1, -1, 0, 1, 1, 1, 0,-1};
char s[] = "OIE";
int main() {
int n, m;
while (cin >> n >> m) {
int res = 0;
vector<vector<char> > S(n, vector<char>(m));
for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> S[i][j];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
for (int d = 0; d < 8; ++d) {
bool trobat = true;
for (int h = 0; h < 3 and trobat; ++h) {
int f = i + arrf[d], c = j + arrc[d];
if (f < 0 || f >= n || c < 0 || c >= m || S[f][c] != s[h])
trobat = false;
}
if (trobat) res++;
}
}
}
cout << res << endl;
}
}
Could somebody help me to fix this? I would appreciate.
Regards.
One error is that this line
int f = i + arrf[d], c = j + arrc[d];
should be
int f = i + h*arrf[d], c = j + h*arrc[d];
With your code it doesn't matter how many times you go round the inner loop you are still checking the same position.