Auto-correlation/correlation in C++ - c++

The following function computes the correlation between two vectors.
It doesn't give the same result as matlab function for small values:
I am really don't know if the bug becomes from this function or not ? the maximum lags by default is N-1 ? is this reasonable ?
inline int pow2i(int x) { return ((x < 0) ? 0 : (1 << x)); }`
vec xcorr(vec x, vec y,bool autoflag)
{
int maxlag=0;
int N = std::max(x.size(), y.size());
//Compute the FFT size as the "next power of 2" of the input vector's length (max)
int b = ceil(log2(2.0 * N - 1));
int fftsize = pow2i(b);
int e = fftsize - 1;
cx_vec temp2;
if (autoflag == true) {
//Take FFT of input vector
cx_vec X = cx_vec(x,zeros(x.size()));
X= fft(X,fftsize);
//Compute the abs(X).^2 and take the inverse FFT.
temp2 = ifft(X%conj(X));
}
else{
//Take FFT of input vectors
cx_vec X=cx_vec(x,zeros(x.size()));
cx_vec Y=cx_vec(y,zeros(y.size()));
X = fft(X,fftsize);
Y = fft(Y,fftsize);
//cout<< "Y " << Y << endl;
//cout<< "X " << X<< endl;
temp2 =ifft(X%conj(Y));
//cout<< "temp 2 " << temp2 << endl;
}
maxlag=N-1;
vec out=real(join_cols(temp2(span(e - maxlag + 1, e)),temp2(span(0,maxlag))));
return out;
}

Just implement autocorrelation in time-domain, as one of the comments mentioned.
Armadillo does not have cross-correlation (and autocorrelation) implemented, but one easy way to implement them is using convolution, which armadillo does have. You just need to invert the other of the elements in the second vector and arma::conv will be essentially be computing the cross-correlation.
That is, you can easily compute the autocorrelation with of an arma::vec a with
arma::vec result = arma::conv(a, arma::reverse(a));
This gives the same result that xcorr in MATLAB/Octave returns (when you pass just a single vector to xcorr it computes the autocorrelation).
Note that you might want to divide result by N or by N-1.

Related

Procedure that generate the polynomial coefficients and a function to calculate the value of it

So essentially, I'm trying to code a small block that should create or generate coefficients for polynomial n-degree that can be represented through vector which is a=[a0, a1..an] given the basic formula is
Well, the issue is when doing a function to get value of polynomial P from point "x" it returns value from entirely using Horner's Rule which it's not the same result as intended although not sure which one I should put on. The math basic explanation tells me at least something out of:
E.g: n=2; (A[i] stack terms by 4, 2, 1) and calculates P(value of x) = 4 * x ^ 0 – 2 * x ^ 1 + 1 * x ^ 2 = 4 – 2x + x2 = x2 – 2x + 4 = 4
With other words , can't find the culprit when for "x" value is meant to go through "i" variable numbered wrong by exponent and the result gets output for P(0)=7 while it shouldn't be and concrete as in P(0) = 0 ^ 2 – 2 * 0 + 4 = 4
Here's a little snippet went through so far, I would appreciate if someone could point me in the right direction.
double horner(const double&x, const int& n, const double& nn) {
if (n < 0)
return nn;
else {
double m; cin>>m;
return horner(x, n-1, nn*x+m);
}
}
int main() {
int n;double x;
cout << "n=";cin >> n;
cout << "x=";cin >> x;
cout << "P(0)=" << horner(x, n, 0);
return 0;
}
Edit: My brain farted for a moment somewhere while was coding and continuously revising the case, I forgot to mention what exactly are the parts of each variables for the program to avoid confusion yes, so:
n, polynomial grade;
p, polynomial coefficient;
x, the point in which evaluates;
And here given the grade equation to polynomial
which any negative and positive input terms adding by exponent to these coefficients are the steps that holds the result exception, hence the reason Horner's rule that it reduces the number of multiplication operations.
Edit: After few hours, managed to fix with polynomial evaluating issue, the only question remains how I'd suppose to generate coefficients using method std::vector ?
float honer(float p[], int n, float x)
{
int i;
float val;
val = p[n];
for (i = n - 1; i >= 0; i--)
val = val * x + p[i];
return val;
}
int main()
{
float p[20]; // Coefficient of the initial polynomial
int n; // Polynomial degree -n
float x; // Value that evaluates P -> X
cout << "(n) = ";
cin >> n;
for (int i = n; i >= 0; i--)
{
cout << "A[" << i << "]=";
cin >> p[i];
}
cout << "x:= ";
cin >> x;
cout << "P(" << x << ")=" << honer(p, n, x);
//Result (input):
//n: 2,
//P[i]: 4, -2, 1 -> x: 0, 1
// Result (output):
//P() = 4
}
Expect some certain output scenarios given below input if assigned:

Failed to use cs_qrsol from CXSparse to solve x=A\b in C++ when A matrix is large

I am trying to solve a linear equation system x = A\b, using CXSparse library by Tim Davis (http://faculty.cse.tamu.edu/davis/suitesparse.html). I develop my C++ program (with OpenCV) using MS Visual Studio 2012 on Windows 7 x64.
I have an A matrix, which is a sparse matrix and b matrix. I want to find x = A\b. My A matrix is of size ~ 700,000 x 30,000. Since this is not a square matrix, I call the function cs_qrsol (as this function accept a non-square mxn matrix.
I have tried cs_qrsol to solve a small problem using my code below, and it gives an expected result. However, when I tried to apply it with my real A matrix, the function always returns 0. (I have tried order = 0 to 3).
To proof that my problem A, b has a solution x, I input the matrix A,b in MATLAB and I can get the results successfully.
So, I was wondering there might be something wrong with my code or there is any limitation on the function??. I would really appreciate if anybody could help point out what I did wrong. Thank you very much.
bool sparseSolve(cv::Mat& i, cv::Mat& j, cv::Mat& s, cv::Mat& d, int k, int n)
{
// Solve linear equations: x = A\b
// i,j,s are (k x 1) matrices - (i,j) are row and col, s are values so the trippet is (i,j,s)
// d is an (n x 1) matrix - this is the b matrix
cs *T, *A;
double * b;
int y, m, status;
// Assign the sparse matrix A
T = cs_spalloc (0, 0, 1, 1, 1) ;
for (y = 0; y < k; y++)
{
if (!cs_entry (T, i.at<int>(y,0), j.at<int>(y,0), s.at<double>(y,0)))
{
cs_spfree(T);
std::cout << "Failed to add entry to the matrix A at " << y << std::endl;
return false;
}
}
A = cs_compress(T);
cs_spfree(T);
if (!A)
{
std::cout << "Failed to create A as the compressed-column form of T" << std::endl;
return false;
}
m = A->m; // # rows of A
if (n != m)
std::cout << "# rows of A (" << m << ") not equal # equations (" << n << ")" << std::endl;
// Allocate the b matrix
b = static_cast<double *>(malloc(n*sizeof(double)));
if (!b)
{
std::cout << "Failed to allocate the b matrix" << std::cout;
cs_spfree(A);
return false;
}
// Assign the b matrix
for (y = 0; y < n; y++)
{
b[y] = d.at<double>(y,0);
}
// Obtain the results x=A\b in the b matrix
status = cs_cholsol(0, A, b); // This returns 0 as failed.
cs_spfree(A);
free(b);
return (1==status);
}
Now, I can solve my own problem.
I made change to my program to call the version cs_dl_* instead of cs_* functions. Also, the memory in my machine is really relevant. To make it work, I have to close all the opened application to make sure that I have enough space of memory for cs_spalloc or cs_dl_spalloc.

Accessing an element of an Array in OpenCV

I am trying to get the value of an element in an array in order to use it in an if statement but unfortunately the following code is not working for me. The cout of comp is not matching the first element of the array C. I'm new to OpenCV so any help is appreciated.
Mat A = (Mat_<double>(2,1) << u, v);
Mat B = (Mat_<double>(2,6) << -1/Z, 0 , x/Z , x*y , -(x*x+1),y,
0 ,-1/Z, y/Z ,y*y+1, -x*y ,-x);
Mat pinvB = B.inv(DECOMP_SVD);
Mat C=pinvB*A; // 6x1 Array
float comp = C.at<float>(0,0);
cout << "comp " << comp << endl; //This value does not match C[0,0]
cout << "C " << C << endl;
if (comp < 0.0001){
//process
}
Your Mat_<double> instances internally store doubles. When you do this:
float comp = C.at<float>(0,0);
you are trying to use some of the bits that form a double, and interpret them as a float. Floating point representation means that half of the bits of a double don't translate into a meaningful float (assuming a platform where float has half the size of a double, which is quite common). So, call C.at<double> instead.
Actually, if you use the template version of cv::Mat_<_Tp>, you can access pixel value by Mat_<_Tp>::operator ()(int y, int x)
cv::Mat_<double> M(3, 3);
for (int i = 0;i < 3; ++i) {
for (int j = 0;j < 3; ++j) {
std::cout<<M(i, j)<<std::endl;
}
}
so that later if you change the template argument from double to float, you don't need to modify each at().

Problems with cout ( C++)

I am having the hardest time figuring out what is wrong here:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double fact(double);
double sinTaylor(double);
double cosTaylor(double);
int main()
{
double number, sineOfnumber, cosineOfnumber;
cout << "Enter a number, then I will calculate the sine and cosine of this number" << endl;
cin >> number;
sineOfnumber = sinTaylor(number);
cosineOfnumber = cosTaylor(number);
cout << fixed << endl;
cout << cosineOfnumber << endl;
cout << sineOfnumber << endl;
return 0;
}
double fact(double n)
{
double product = 1;
while(n > 1)
product *= n--;
return product;
}
double sinTaylor(double x)
{
double currentIteration, sumSine;
for(double n = 0; n < 5; n++)
{
currentIteration = pow(-1, n)*pow(x, 2*n+1) / fact(2*n+1);
sumSine += currentIteration;
}
return sumSine;
}
double cosTaylor(double y)
{
double currentIteration, sumCosine;
for(double n = 0; n < 5; n++)
{
double currentIteration = pow(-1, n)*pow(y, 2*n) / fact(2*n);
sumCosine += currentIteration;
}
return sumCosine;
}
Ok, so here's my code. I'm pretty content with it. Except for one thing:
sineOfnumber and cosOfnumber, after the calling of sinTaylor and cosTaylor, will add each other in the following cout line that will print each other.
In other words, if number is equal to lets say, .7853, 1.14 will be printed in the line that is intended to print cosineOfnumber, and sineOfnumber will print the result normally.
Can anyone help me identify why this is? Thank you so much!
Are you ever initializing the variables sumSine and sumCosine in your functions? They're not guaranteed to start at zero, so when you call += inside your loop you could be adding computed values to garbage.
Try initializing those two variables to zero and see what happens, as other than that the code seems okay.
The series for the sine is (sorry for the LaTeX):
sin(x) = \sum_{n \ge 0} \frac{x^{2 n + 1}}{(2 n + 1)!}
If you look, given term t_{2 n + 1} you can compute term t_{2 n + 3} as
t_{2 n + 3} = t_{2 n + 1} * \frac{x^2}{(2 n + 2)(2 n + 3)}
So, given a term you can compute the next one easily. If you look at the series for the cosine, it is similar. The resulting program is more efficient (no recomputing factorials) and might be more precise. When adding up floating point numbers, it is more precise to add them from smallest to largest, but I doubt that will make a difference here.

How to optimize a for loop?

I have a problem, let's say:
Find all two pairs of numbers (x,y) and (z,t) such that x³ + y³ = z³ + t³, where (x, y) != (z, t) and x³ + y³ < 10,000.
Taking the cube root of 10,000 yeilds 21.544 -> round down to 21, so I got:
#include <iostream>
using namespace std;
int main() {
for( int x = 1; x <= 20; ++x ) {
for( int y = x + 1; y <= 21; ++y ) {
for( int z = x + 1; z <= y - 1; ++z ) {
for( int t = z; t <= y - 1; ++t ) {
if( x*x*x + y*y*y == z*z*z + t*t*t ) {
cout << x << ", " << y << ", " << z << ", " << t << endl;
}
}
}
}
}
return 0;
}
I know this code could be optimized more, and that's what I'm looking for. Plus, one of my friends told me that y could be x + 2 instead of x + 1, and I doubt this since if
x = 1, then we will never have y = 2, which in this case missed one possible solution.
Any thought?
Well there's one obvious algorithmic optimization that can be made given the current loop structure, you optimize quite rightly by limiting your ranges to the cube root of 10,000. However you can go farther and limit your range on y based on the cube root of 10,000 - x. That's one thing you can do.
The other optimization is that there's no reason on earth that this should be 4 loops. Simply do 2 loops and compute the values of x^3 + y^3 and check for duplicates. (This is as good as you're going to get without delving into features of cube roots.)
This isn't actually using the API correctly but you get the idea:
multimap<int, std::pair<int, int> > map;
for (int i = 1; i < 21; i++) {
(for int j = x; j < cube_root(10000 - i^3); j++ {
multimap.insert (i^3 + j^3, std::pair<int, int>(i,j);
Then you just iterate through the multimap and look for repeats.
Typical tradeoff: memory for speed.
First the bound on x is quite large: if we suppose that (x,y) is ordered with x <= y, then
x^3 + y^3 < N and x^3 < y^3 (for positive numbers)
=> x^3 + x^3 < N (by transitivity)
<=> x^3 < N/2
<=> x <= floor((N/2)^(1/3))
Thus x <= 17 here.
Now, let us memoize the result of x^3 + y^3 and build an associative table (sum -> pairs). By the way, is there a reason to discard (x,x) as a pair ?
int main(int argc, char* argv[])
{
typedef std::pair<unsigned short, unsigned short> Pair;
typedef std::vector<Pair> PairsList;
typedef std::unordered_map<unsigned short, PairsList> SumMap;
// Note: arbitrary limitation, N cannot exceed 2^16 on most architectures
// because of the choice of using an `unsigned short`
unsigned short N = 10000;
if (argc > 1) { N = boost::lexical_cast<unsigned short>(argv[1]); }
SumMap sumMap;
for (unsigned short x = 1; x*x*x <= N/2; ++x)
{
for (unsigned short y = x; x*x*x + y*y*y <= N; ++y)
{
sumMap[x*x*x + y*y*y].push_back(Pair(x,y));
}
}
for (SumMap::const_reference ref: sumMap)
{
if (ref.second.size() > 1)
{
std::cout << "Sum: " << ref.first
<< " can be achieved with " << ref.second << "\n";
// I'll let you overload the print operator for a vector of pairs
}
}
return 0;
}
We are O(N^2) here.
Make a list of all numbers and their operational result. Sort the list by the results. Test matching results for having different operands.
Use a table from sums to the set of pairs of numbers generating that sum.
You can generate that table by two nested for loops, and then run through the table collecting the sums with multiple solutions.
I'd suggest calculating the powers in outer loops (EDIT: Moved calculations out of the for loops):
int x3, y3, z3;
for( int x = 1; x <= 20; ++x ) {
x3 = x * x * x;
for( int y = x + 1; y <= 21; ++y ) {
y3 = y * y * y;
for( int z = x + 1; z <= y - 1; ++z ) {
z3 = z * z * z;
for( int t = z; t <= y - 1; ++t ) {
if( x3 + y3 == z3 + t*t*t ) {
cout << x << ", " << y << ", " << z << ", " << t << endl;
}
}
}
}
}
Anyway, why do you want to optimize (at least for this example)? This runs in 20 ms on my PC... So I guess you have similar problems at a larger scale.
As a general summary:
Calculate the cubes as you loop rather than at the end, thus int xcubed = x*x*x; just after the loop of x (similarly with y and z). This saves you calculating the same values multiple times. Put them in a table so you only calculate these once.
Create a table of sums of cubes, using a hash_table of some extent, and let it hold duplicates (not to be confused with a hashed-collision).
Any that has a duplicate is a solution.
1729 should come up as one of your solutions by the way. 1 cubed plus 12 cubed and also 9 cubed + 10 cubed.
To test performance you could of course pick a much higher value of maxsum (as well as run it several times).
The algorithm is strictly O(N^2/3). (2/3 because you go only to the cube-root of N and then it is O(m^2) on that smaller range).