-7

In order to complete my project I need a to incorporate a function that return a vector (STL). The following function when run with the online compiler from http://en.cppreference.com does return a vector :

#include <cstddef>
#include <utility>
#include <numeric>
#include <complex>
#include <valarray>
#include <vector>
#include <iostream>

typedef std::complex<double> Complex;
typedef std::valarray <Complex> CArray;

int long Gidx=0;
std::vector<int long>ar;

std::vector<int long> tet(CArray& y) {
     auto max_index = std::max_element (std::begin(y), std::end(y),
         [](const Complex& a ,const Complex& b)
         {
             return a.real() < b.real() ;
         }
     );
     std::cout << "index of  first max element is " << max_index-std::begin(y)+1 << '\n';
     std::cout << "indices of all matches of max element is: " << "[";

     for (auto it= std::begin(y), end = std::end(y); it != end; ++it){
        if(it->real() == max_index->real()) {
            std::cout << it - std::begin(y) +1 <<' ' ;

            Gidx= it - std::begin(y) +1;
            ar.push_back(Gidx);
         }

     }

     std::cout << "]"<<std::endl;
     return ar;
}

int main() {


    CArray m({{0.12,1},{0.04,4},{0.12,6},{0.01, 2}, {0.03, 4}, {0.12, 0}, {0.09, 0}, {0.07, 0}, {0.09, 0},{0.12,4}});

    std::vector<int long> Gidx4=tet(m);
    //std::valarray<int long>Gidx5 = Gidx4;
    //std::cout << Gidx4[3] << std::endl;
    //double ix=Gidx4[1];
    //std::cout << ix << std::endl;
}

Output:

index of  first max element is 1
indices of all matches of max element is: [1 3 6 10 ]

The strange thing is when I am trying to use the same part of code in my program (see below) the result is different (It is returning only the last element of the vector) while the vector contains 5 elements

My program:

//iterDelayEst.cpp
#include <cstddef>
#include <utility>
#include <numeric>
#include <vector>
#include "myexternval.cpp"

/***********************get all indices corresponding to the max element*********************
*********************************************************************************************/
std::vector<int long> tet(CArray& y) {
     auto max_index = std::max_element (std::begin(y), std::end(y),
         [](const Complex& a ,const Complex& b)
         {
             return a.real() < b.real() ;
         }
     );
     std::cout << "index of  first max element is " << max_index-std::begin(y)+1 << '\n';
     std::cout << "indices of all matches of max element is: " << "[";

     for (auto it= std::begin(y), end = std::end(y); it != end; ++it){
        if(it->real() == max_index->real()) {
            std::cout << it - std::begin(y)+1 <<' ';

            Gidx= it - std::begin(y)+1;
            ar.push_back(Gidx);
         }
     }
     std::cout <<"]"<<std::endl;
     return ar;
}
/*******************************xcorr function*************************************************
**********************************************************************************************/
/*
void xcorr(CArray& x, int n){
             int i;   
             fft(x);
         x *=x.apply(std::conj);
         ifft(x);
         for ( i = 0 ; i < n ; i++ ){
             cout << "x[" << i <<"] =" << x[i] << endl;
             }
      }
*/
/******************************iterDelayEst*****************************************************
************************************************************************************************/
double iterDelayEst(int n,CArray& x, CArray& y)
{   /***************************constants************************************************/
    //exit if uncertainty below threshold
    int j;
    double thr_samples = 1e-7;
    double halfN= floor (n/2);
    //exit after fixed number of iterations
    double nIter = 25;
    fft(x);
    fft(y);
    //frequency domain representation of signals
    std::vector<double> tau;
    auto f = binFreq(n);
    std::vector<double> e;
        Complex nf4(0.0,0.0);
        Complex nf5(0.0,0.0);

    for ( j = 0 ; j < n ; j++ )
    {
        auto nfa=(x * x.apply(std::conj));
        nf4 +=nfa[j];

        auto nfb=(y * y.apply(std::conj));
        nf5 +=nfb[j];

    }

    auto nf1 = (nf4 * nf5);
    auto nf2 =std::sqrt(nf1);
    auto nf =nf2/(double)n;
    cout << "nf1" << nf1 <<endl;
    cout << "nf2" << nf2 <<endl;
    cout << "nf" << nf <<endl;

    double x1=-1;
    double x2=-1;
    double x3=-1;
    double y1=-1;
    double y2=-1;
    double y3=-1;
    int i;
    /****************************iteration loop*************************************
    *******************************************************************************/

    //for(i=0; i<nIter; i++)
                // std::vector<complex<double> > v;
    /****crosscorrelation with time-shifted signal****
    *************************************************/          
        x = x.apply(std::conj);
        y *= x;
        ifft(y);
        y =std::abs(y);
        y=y/nf;

        for ( i = 0 ; i < n ; i++ ){
                cout << "y[" << i <<"] =" << y[i] << endl;
            }

        std::vector<int long> Gidx4=tet(y);

        double ixLow  =fmod((ix -1)-1 , n) +1; //one below
        double ixMid  =ix;
        double ixHigh =fmod((ix -1)+1 , n) +1; //one above

        //delay corresponding to the three bins
        double tauLow =fmod(ixLow -1 + halfN, n) - halfN;
        double tauMid =fmod(ixMid -1 + halfN, n) - halfN;
        double tauHigh =fmod(ixHigh -1 + halfN, n) - halfN;                                                  
}

Output:

...
(-1.78919e-15,-1.78435e-15)
(-1.34929e-16,1.98328e-16)
(-1.46056e-15,1.58589e-15)
nf1(147456,0)
nf2(384,0)
nf(12,0)
y[0] =(0.583333,0)
y[1] =(0.583333,0)
y[2] =(0.5,0)
y[3] =(0.416667,0)
y[4] =(0.333333,0)
y[5] =(0.333333,0)
y[6] =(0.333333,0)
y[7] =(0.333333,0)
y[8] =(0.416667,0)
y[9] =(0.416667,0)
y[10] =(0.5,0)
y[11] =(0.583333,0)
y[12] =(0.416667,0)
y[13] =(0.333333,0)
y[14] =(0.25,0)
y[15] =(0.0833333,0)
y[16] =(0.0833333,0)
y[17] =(0.166667,0)
y[18] =(0.333333,0)
y[19] =(0.5,0)
y[20] =(0.5,0)
y[21] =(0.5,0)
y[22] =(0.583333,0)
y[23] =(0.583333,0)
y[24] =(0.5,0)
y[25] =(0.416667,0)
y[26] =(0.25,0)
y[27] =(0.0833333,0)
y[28] =(0.0833333,0)
y[29] =(0.166667,0)
y[30] =(0.333333,0)
y[31] =(0.5,0)
index of  first max element is 23
indices of all matches of max element is: [23 ]
serge@ubuntu:~/Downloads/OpenCV/opencv-2.4.9/build$ 

Can someone help me ?

What I am doing wrong?

Serge
  • 3
  • 5
  • 1
    The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should \[edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Sep 05 '16 at 20:43
  • use `at` method instead of `[]` to find out of bound arrays. That's a start. – Jean-François Fabre Sep 05 '16 at 20:48

1 Answers1

0

Why do you say that this has anything to do with returning a vector? As I read your code, std::max_element is finding the max at index 23, which is the last occurrence of 0.583333. Then you are comparing the other occurrences of 0.583333 to the last one using ==. Are you sure that all the occurrences of 0.583333 are exactly equal? Usually it's better to compare floating-point numbers to within some epsilon, rather than requiring exact equality.

To test my theory, inside the for-loop you can print out it->real() and the boolean result of the == comparison, to see if you are getting one exact match or five exact matches.

D-Von
  • 416
  • 2
  • 5