Single Channel OpenCV Mat.at<> gives out wrong values - c++

Declaring the Mat image, and assigning values.
Mat magnitude = Mat(gradient_columns.cols, gradient_columns.rows, CV_64FC1);
for(int i = 0; i < gradient_columns.cols; i++)
{
for(int j = 0; j < gradient_columns.rows; j++)
{
magnitude.at<double>(Point(i,j)) = (double)hypot(gradient_columns.at<double>(Point(i,j)), gradient_rows.at<double>(Point(i,j)));
}
}
Printing the above Mat:
cout << "M = " << magnitude << endl;
Result:
M = [0, 0, 0.1257399049164523, 12.36316814720732, 12.50461780753356, 0.2674320707434279, 10.39230484541326, 12.03299037437945, 5.430256687374658,
12.03299037437945, 4.684492386402418, 4.72934192083521, 12.16431633381293, 5.397674732957373, 12.30042244512288, 10.25834261322606, 0.3944487245360109,
12.16431633381293, 11.84297951775486, 12.44187210544911, 12.10132213098092,
0.4088817310696626, 10.15078660267586, 12.09573607646389, 2.076275433221507, 0, 0.1257399049164523, 0, 0.1257399049164523, 0;
.....
.....]
The above result is completely correct and as expected.
However if I try to print individual values I get wrong results:
cout.precision(20);
cout << "CHANNELS: " << magnitude.channels() << endl;
cout << magnitude.at<double>(Point(0, 2)) << endl;
cout << magnitude.at<double>(Point(0, 3)) << endl;
cout << magnitude.at<double>(Point(0, 4)) << endl;
cout << magnitude.at<double>(Point(0, 5)) << endl;
Result | Actual Value:
CHANNELS: 1
0.062870 | 0.1257399049164523,
0.000000 | 12.36316814720732,
0.031404 | 12.50461780753356,
0.000000 | 0.2674320707434279
I understand its some data type conversion issue, but if anyone can suggest any solution?
Thanks.

I believe that there is nothing wrong with your matrix. You are just not printing what you think you are.
When writing magnitude.at<double>(Point(0,2)), you're not printing the number in line 0 and column 2 as you expected, but the number in line 2 and column 0. Try to write magnitude.at<double>(0,2) instead.

For those who are having a similar issue and #Sunreef's answer does not work, check if you are accidentally using mat.at<float>(_,_) instead of mat.at<double>(_,_)

Related

ta-lib c++, calculated macd not matched web

I'm using ta-lib c++ library to calculate MACD, but the result is totally different from what the website shows,
the real MACD is [444.39, 505.05, 248.02, -232.33, 100.39, -13.18],
but my result is [282.10, -74.12, -211.27, -460.82, -850.86]
I have set all the MAType to TA_MAType_EMA, but it makes no sense
#include <iostream>
#include <cassert>
#include <ta-lib/ta_libc.h>
using namespace std;
int main()
{
// init ta-lib context
TA_RetCode retcode;
retcode = TA_Initialize();
assert(retcode == TA_SUCCESS);
// comput moving average price
TA_Real close_price_array[100] = { 37924.41, 40849.89, 37952.37, 36564.58, 36844.22, 34719.71, 33156.65, 32858.22,
34212.01, 37118.35, 31924.17, 30327.18, 31757.38, 34459.95, 31952.8 , 31876.57,
32457.32, 31392.34, 34183.43, 37328.12, 36408.31, 35732.04, 37460.76, 35627.27,
39551.87, 34677.01, 33834.78, 31580.01, 39674.77, 40513.11, 40829.87, 38950.0 ,
34555.33, 32091.45, 31737.83, 33506.67, 31695.17, 29190.91, 28779.14, 28153.95,
26617.04, 26911.93, 27360.51, 25625.24, 24019.43, 23230.15, 23450.3 , 23341.65,
23099.56, 23873.04, 23551.1 , 22553.6 , 23329.31, 20659.69, 19406.28, 19198.7 ,
19215.36, 18401.98, 18106.72, 18134.91, 18347.36, 18806.82, 19213.0 , 19126.33,
19107.67, 18945.51, 19533.84, 18891.06, 19265.5 , 19306.92, 18116.34, 17505.0 ,
16502.76, 16905.43, 19129.39, 19358.42, 18269.55, 18294.73, 18784.06, 18655.81,
18046.78, 17871.06, 17318.57, 16450.98, 16026.15, 15950.15, 16098.79, 16122.33,
15666.22, 15168.03, 15004.24, 15354.6 , 15342.63, 15411.23, 15077.18, 13911.95,
13708.92, 13492.15, 13797.96, 13854.39 };
TA_Real *p = close_price_array;
cout.precision(8);
TA_Integer out_begin = 0;
TA_Integer out_nb_element = 0;
TA_Real outMACD[100] = { 0 };
TA_Real outMACDSignal[100] = { 0 };
TA_Real outMACDHist[100] = { 0 };
retcode = TA_MACDEXT(0, 99,
&close_price_array[0],
12, TA_MAType_EMA ,
26, TA_MAType_EMA ,
9, TA_MAType_EMA ,
&out_begin, &out_nb_element,
outMACD, outMACDSignal, outMACDHist);
assert(retcode == TA_SUCCESS);
cout << "out_begin_index: " << out_begin << endl;
cout << "out_nb_element: " << out_nb_element << endl;
cout << "outMACD array: " << endl;
for (auto &i : outMACD)
cout << i << " ";
cout << endl;
cout << "outMACDSignal array: " << endl;
for (auto &i : outMACDSignal)
cout << i << " ";
cout << endl;
cout << "outMACDSignal array: " << endl;
for (auto &i : outMACDHist)
cout << i << " ";
cout << endl;
retcode = TA_Shutdown();
assert(retcode == TA_SUCCESS);
return 0;
}
enter image description here
[After comparing TA-lib results with Excel calculations]: In your excel the 12-day EMA is calculated from the 1st day and its first value is the average on 12th day (8/13/2020) and the 26-day EMA is calculated from 1st day and first value is average on 26th day (26/13/2020). TA-Lib postpones the 12 day EMA calculation start to get its first value on the same day as first value of 26-day EMA. That means 12-day EMA is calculated from 8/16/2020 and it's first value is the average on (26/13/2020) as it's in 26-day EMA. So to adjust your excel to TA-Lib results you need to copy formula =AVERAGE(B19:B30) into the cell C30.
Another note is that TA-Lib's MACD outputs 3 arrays at once: macd, signal, histogram. And thus TA-Lib starts the output at the point it got meaningful values for all 3 result arrays. Thus you're getting result starting not from the point where 26-day EMA can be calculated, but from the point where Signal can be calculated (8 days later). So you shall compare talib_macd[1] with excel starting from cell E38 instead of E30.

Efficient zero padding using cudaMemcpy3D

I would like to transfer a 3d array stored in linear memory on the host, into a larger (3D) array on the device. As an example (see below), I tried to transfer a (3x3x3) array into a (5x5x3) array.
I expect that on the host I get 2D slices with the following pattern:
x x x 0 0
x x x 0 0
x x x 0 0
0 0 0 0 0
0 0 0 0 0
where x are the values of my array. However, I get something like that, where y are the values of the next 2D slice:
x x x 0 0
x x x 0 0
x x x 0 0
y y y 0 0
y y y 0 0
According to the cudaMemcpy3D documentation I would have expect that the extent parameter would take into account the padding in the vertical axis but apparently not.
Am I mistaken in the understanding of the documentation? If yes, is there any other way to perform this operation? The final size of the array to transfer will be 60x60x900 into an array of size 1100x1500x900. I use the zero padding to prepare a Fourier transform.
Here is the simplified code that I used:
cudaError_t cuda_status;
cudaPitchedPtr d_ptr;
cudaExtent d_extent = make_cudaExtent(sizeof(int)*5,sizeof(int)*5,sizeof(int)*3);
cudaExtent h_extent = make_cudaExtent(sizeof(int)*3,sizeof(int)*3,sizeof(int)*3);
int* h_array = (int*) malloc(27*sizeof(int));
int* h_result = (int*) malloc(512*sizeof(int)*5*3);
for (int i = 0; i<27; i++)
{
h_array[i] = i;
}
cuda_status = cudaMalloc3D(&d_ptr, d_extent);
cout << cudaGetErrorString(cuda_status) << endl;
cudaMemcpy3DParms myParms = {0};
myParms.extent = h_extent;
myParms.srcPtr.ptr = h_array;
myParms.srcPtr.pitch = 3*sizeof(int);
myParms.srcPtr.xsize = 3*sizeof(int);
myParms.srcPtr.ysize = 3*sizeof(int);
myParms.dstPtr = d_ptr;
myParms.kind = cudaMemcpyHostToDevice;
cuda_status = cudaMemcpy3D(&myParms);
cout << cudaGetErrorString(cuda_status) << endl;
cout << "Pitch: " << d_ptr.pitch << " / xsize:" << d_ptr.xsize << " / ysize:" << d_ptr.ysize << endl; // returns Pitch: 512 / xsize:20 / ysize:20 which is as expected
// Copy array to host to be able to print the values - may not be necessary
cout << cudaMemcpy(h_result, (int*) d_ptr.ptr, 512*5*3, cudaMemcpyDeviceToHost) << endl;
cout << h_result[128] << " " << h_result[3*128] << " " << h_result[5*128] << " " << endl; // output : 3 9 15 / expected 3 0 9
The problems here have to do with your extents and sizes.
When an extent is used with cudaMemcpy3D for the non-cudaArray case, it is intended to provide the size of the region in bytes. A way to think about this is that product of the 3 dimensions of the extent should yield the size of the region in bytes.
What you're doing however is scaling each of the 3 dimensions by the element size, which is not correct:
cudaExtent h_extent = make_cudaExtent(sizeof(int)*3,sizeof(int)*3,sizeof(int)*3);
^^^^^^^^^^^
this is the only element scaling expected
You've made a similar error here:
myParms.srcPtr.xsize = 3*sizeof(int); // correct
myParms.srcPtr.ysize = 3*sizeof(int); // incorrect
We only scale the x (width) dimension by the element size, we don't scale the y (height) or z (depth) dimensions.
I haven't fully verified your code, but with those 2 changes, your code produces the output you indicate is expected:
$ cat t1593.cu
#include <iostream>
using namespace std;
int main(){
cudaError_t cuda_status;
cudaPitchedPtr d_ptr;
cudaExtent d_extent = make_cudaExtent(sizeof(int)*5,5,3);
cudaExtent h_extent = make_cudaExtent(sizeof(int)*3,3,3);
int* h_array = (int*) malloc(27*sizeof(int));
int* h_result = (int*) malloc(512*sizeof(int)*5*3);
for (int i = 0; i<27; i++)
{
h_array[i] = i;
}
cuda_status = cudaMalloc3D(&d_ptr, d_extent);
cout << cudaGetErrorString(cuda_status) << endl;
cudaMemcpy3DParms myParms = {0};
myParms.extent = h_extent;
myParms.srcPtr.ptr = h_array;
myParms.srcPtr.pitch = 3*sizeof(int);
myParms.srcPtr.xsize = 3*sizeof(int);
myParms.srcPtr.ysize = 3;
myParms.dstPtr = d_ptr;
myParms.kind = cudaMemcpyHostToDevice;
cuda_status = cudaMemcpy3D(&myParms);
cout << cudaGetErrorString(cuda_status) << endl;
cout << "Pitch: " << d_ptr.pitch << " / xsize:" << d_ptr.xsize << " / ysize:" << d_ptr.ysize << endl; // returns Pitch: 512 / xsize:20 / ysize:20 wich is as expected
// Copy array to host to be able to print the values - may not be necessary
cout << cudaMemcpy(h_result, (int*) d_ptr.ptr, d_ptr.pitch*5*3, cudaMemcpyDeviceToHost) << endl;
cout << h_result[128] << " " << h_result[3*128] << " " << h_result[5*128] << " " << endl; // output : 3 9 15 / expected 3 0 9
}
$ nvcc -o t1593 t1593.cu
$ cuda-memcheck ./t1593
========= CUDA-MEMCHECK
no error
no error
Pitch: 512 / xsize:20 / ysize:5
0
3 0 9
========= ERROR SUMMARY: 0 errors
$
I should also point out that the strided memcpy operations in CUDA (e.g. cudaMemcpy2D, cudaMemcpy3D) are not necessarily the fastest way to conduct such a transfer. You can find writeups of this characteristic in various questions about cudaMemcpy2D here on SO cuda tag.
The net of it is that it may be faster to transfer the data to the device in an unstrided, unpadded linear transfer, then write a CUDA kernel to take the data that is now on the device, and place it in the array of interest, with appropriate striding/padding.

Getting wrong values from a vector of structs in C++

It have been years since i last programmed with vectors and other structures (most of them in college) and now I'm having a problem that i can't identify for sure most for this knowledge gap.
So, here's the part of the code I think it's with problems:
if (pos == -1) {
cout<< "New Neighbor\n";
neighborRecord newRec; //declaring newRec as type struct neighborRecord
newRec.id = nodeID; //receiving values
newRec.x = x_ngb;
newRec.y = y_ngb;
newRec.z = z_ngb;
newRec.x_dst = x_dst; //L
newRec.y_dst = y_dst;
newRec.z_dst = z_dst;
newRec.ts = simTime().dbl();
newRec.timesRx = 1;
newRec.ic = IC;
cout<< "NEW REC IC" << newRec.ic<<"\n"; //until here i checked and it's all ok with variables
neighborTable.push_back(newRec);
But then when I make a loop for reading the vector, I get wrong values.
Here's the loop:
for (int i = 0; i < neighborTable.size(); i++){
trace()<< "ID: "<< neighborTable[i].id <<"\n";
trace()<< "X : "<< neighborTable[i].x<<"\n";
trace()<< "Y : "<< neighborTable[i].y<<"\n";
trace()<< "Z : "<< neighborTable[i].z<<"\n";
trace()<< "XDST: "<< neighborTable[i].x_dst<<"\n";
trace()<< "YDST: "<< neighborTable[i].y_dst<<"\n";
trace()<< "ZDST: "<< neighborTable[i].z_dst<<"\n";
trace()<< "TS: "<< neighborTable[i].ts <<"\n";
trace()<< "TIMESRX: "<< neighborTable[i].timesRx<<"\n";
trace()<< "IC: "<< neighborTable[i].ic<<"\n";
}
One of the results:
ID: 30
X : 26.4458
Y : 38.1514
Z : 0
XDST: 5.43472e-323
YDST: 51.8989
ZDST: 50.9054
TS: 1.13635e-322
TIMESRX: 20615843
IC: 0
I don't know if it's something when accessing the vector and I don't know how make this work. Funny fact, I've tested with less variables and it works alright. I've just seen this error when I added more variables to the struct.

Armadillo: changing a subview to the same value

I have just started using Armadillo and I am trying to change some of the values in a vector to the same value. I know for changing to 0 or 1 you can do it easily.
Why does the last line in this not work? The only way I have found to do this is much more complicated.
arma::vec x = arma::linspace<arma::vec>(1, 20, 10);
std::cout << x << std::endl;
x(arma::find(x > 15)).ones();
std::cout << x << std::endl;
x(arma::find(x < 6)) = arma::datum::nan; // this doesn't compile
// this is how I got it to work but is there a better way?
arma::uvec idx = find(x < 6);
arma::vec idxrepl(idx.n_elem);
idxrepl.fill(arma::datum::nan);
x.elem(idx) = idxrepl;
std::cout << x << std::endl;
thanks
Try:
x(arma::find(x < 6)).fill(arma::datum::nan);

Values not written to vector

I'm trying to read pairs values from a file in the constructor of an object.
The file looks like this:
4
1 1
2 2
3 3
4 4
The first number is number of pairs to read.
In some of the lines the values seem to have been correctly written into the vector. In the next they are gone. I am totally confused
inline
BaseInterpolator::BaseInterpolator(std::string data_file_name)
{
std::ifstream in_file(data_file_name);
if (!in_file) {
std::cerr << "Can't open input file " << data_file_name << std::endl;
exit(EXIT_FAILURE);
}
size_t n;
in_file >> n;
xs_.reserve(n);
ys_.reserve(n);
size_t i = 0;
while(in_file >> xs_[i] >> ys_[i])
{
// this line prints correct values i.e. 1 1, 2 2, 3 3, 4 4
std::cout << xs_[i] << " " << ys_[i] << std::endl;
// this lines prints xs_.size() = 0
std::cout << "xs_.size() = " << xs_.size() << std::endl;
if(i + 1 < n)
i += 1;
else
break;
// this line prints 0 0, 0 0, 0 0
std::cout << xs_[i] << " " << ys_[i] << std::endl;
}
// this line prints correct values i.e. 4 4
std::cout << xs_[i] << " " << ys_[i] << std::endl;
// this lines prints xs_.size() = 0
std::cout << "xs_.size() = " << xs_.size() << std::endl;
}
The class is defined thus:
class BaseInterpolator
{
public:
~BaseInterpolator();
BaseInterpolator();
BaseInterpolator(std::vector<double> &xs, std::vector<double> &ys);
BaseInterpolator(std::string data_file_name);
virtual int interpolate(std::vector<double> &x, std::vector<double> &fx) = 0;
virtual int interpolate(std::string input_file_name,
std::string output_file_name) = 0;
protected:
std::vector<double> xs_;
std::vector<double> ys_;
};
You're experiencing undefined behaviour. It seems like it's half working, but that's twice as bad as not working at all.
The problem is this:
xs_.reserve(n);
ys_.reserve(n);
You are only reserving a size, not creating it.
Replace it by :
xs_.resize(n);
ys_.resize(n);
Now, xs[i] with i < n is actually valid.
If in doubt, use xs_.at(i) instead of xs_[i]. It performs an additional boundary check which saves you the trouble from debugging without knowing where to start.
You're using reserve(), which increases capacity (storage space), but does not increase the size of the vector (i.e. it does not add any objects into it). You should use resize() instead. This will take care of size() being 0.
You're printing the xs_[i] and ys_[i] after you increment i. It's natural those will be 0 (or perhaps a random value) - you haven't initialised them yet.
vector::reserve reserve space for further operation but don't change the size of the vector, you should use vector::resize.