Thread: problem with matrix size declaration

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    12

    Unhappy problem with matrix size declaration

    Hi
    I keep on having an error when I run this program. The error says:

    Matrix Class Error: Array index out of bounds
    Invalid index 79 was passed. Valid index range is >= 0 and < 79

    which was for matrix P, although I declared the matrix to be 605x605. Any suggestions?

    Code:
    // standard include files
    // custom include files
    #include "matrix.hpp"
    
    using namespace std;
    
    // Templated helper function to square a value
    template< class T >
    T sq( const T& x )
        { return x*x; }
    
    const double c = 299792458.0;   // Speed of light
    
    // GPS range observation
    
    struct RangeRecord
    {
    	// Data members
    	unsigned prn;
    	double   time;
    	double   position[3];
    	double   pseudorange;       // range measurement
    	double   pseudorangeStdDev; // range measurement std. dev.
    
        bool read( istream& input );
    };
    
    bool readRanges( const string& filename, vector<RangeRecord>& ranges );
    int no_epochs(vector<RangeRecord>& ranges);
    
    int main(int argc, char* argv[] )
    {
    int n, u; 
    int epochs=0;
    
    //files are inputted correctly
    
        // -- Perform adjustment ------------------------------------------------
    
    n = ranges.size();
    u = 3 + no_epochs(ranges);
    
    //matrices
        Matrix<double> P(n, n); 
    
    //Create weight matrix, P
    create_weight(P, ranges, n);
    
    P.print(cout, 2, 5);
    
    return EXIT_SUCCESS;
    
    }
    
    void create_weight(Matrix<double>& P, vector<RangeRecord>& ranges, int n)
    {
      for(int i=0; i<n; i++)
      {
        for(int j=0; j<n; j++)
        {
          if(i==j)
            P[i][i]=1/(sq(ranges[i].pseudorangeStdDev));
          else
            P[i][j]=0;
        }
      }
    }
    
    int no_epochs(vector<RangeRecord>& ranges)
    {
        int number=0;
        for(int i=0; i < ranges.size(); i++)
        {
                if(ranges[i].time!=ranges[i+1].time)
                            number++;  
        }
    
        return number;  
    }
    
    // Read a range record from a file
    //
    // Returns:
    //  true  - input was successful
    //  false - input failed
    //
    // Parameters:
    //  input - input file stream that has already been opened
    
    bool RangeRecord::read( istream& input )
    {
        input >> prn
              >> time
              >> position[0] >> position[1] >> position[2] 
              >> pseudorange
              >> pseudorangeStdDev;
       
        if( !input )
            return false;
    
        return true;
    }
    
    
    // Read the configuration from a file
    //
    // Returns:
    //  true  - input was successful
    //  false - input failed
    //
    // Parameters:
    //  filename - Path of file containing ranges
    //  ranges   - Array of ranges
    bool readRanges( const string& filename, vector<RangeRecord>& ranges )
    {
    int size;
    
        ifstream input( filename.c_str() );
        if( !input )
            return false;
    
       input >> size;
       ranges.resize(size); //Changes size of vector to hold records
    
        for(int i = 0; i < size ; i++)
    {
         if(!ranges[i].read(input))
    			return false;
    }
    
    
    return true;
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Is this:
    Code:
    //files are inputted correctly
    a replacement for actual code that you have omitted?

    Have you tried printing out n in this section:
    Code:
    n = ranges.size();
    u = 3 + no_epochs(ranges);
    
    //matrices
        Matrix<double> P(n, n);

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    12
    Quote Originally Posted by matsp View Post
    Is this:
    Code:
    //files are inputted correctly
    a replacement for actual code that you have omitted?

    Have you tried printing out n in this section:
    Code:
    n = ranges.size();
    u = 3 + no_epochs(ranges);
    
    //matrices
        Matrix<double> P(n, n);

    --
    Mats
    yeah, i tried printing out n and it was 605. And yes, the //files are inputted correctly was actual code i omitted, but i don't think they had any relevance to the problem.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Well, I don't know then - is there anything in the Matrix code that limits the size of 80?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    12
    Quote Originally Posted by matsp View Post
    Well, I don't know then - is there anything in the Matrix code that limits the size of 80?

    --
    Mats
    well, here's the relevant matrix.hpp code:

    Code:
    inline void checkIndex (int index, int maxIndex)
    
    {
    
           if (maxIndex == 0)
    
           {
    
           std::cerr << "Matrix Class Error: Cannot index matrix with zero rows and/or cols" << std::endl;
    
                   exit (1);
    
           }
    
    
    
           if (index < 0 || index >= maxIndex)
    
           {
    
                   std::cerr << "Matrix Class Error: Array index out of bounds" << std::endl;
    
                   std::cerr << "Invalid index " << index << " was passed.";
    
                   std::cerr << " Valid index range is >= 0 and < " << maxIndex << std::endl << std::endl;
    
                   exit (1);
    
           }
    
    }

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    judging by the values printed above, it appears that 605 is bigger than maxIndex, since maxIndex is 79 according to the printout.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    12
    how could maxIndex be 79, though?

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by angelica View Post
    how could maxIndex be 79, though?
    Probably if n is 79.

  9. #9
    Registered User
    Join Date
    Apr 2008
    Posts
    12
    Quote Originally Posted by tabstop View Post
    Probably if n is 79.
    lol i 'cout'ed the value of n though and it was 605

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by tabstop View Post
    Probably if n is 79.
    But in previous posts we have established that n is 605 - I suspect that maxIndex is a constant defined in the matrix.hpp source code - but I don't know, since I have not seen that part of the code.

    What does the line of code calling checkIndex() look like?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Registered User
    Join Date
    Apr 2008
    Posts
    12
    Quote Originally Posted by matsp View Post
    But in previous posts we have established that n is 605 - I suspect that maxIndex is a constant defined in the matrix.hpp source code - but I don't know, since I have not seen that part of the code.

    What does the line of code calling checkIndex() look like?

    --
    Mats
    Code:
    void checkIndex (int index, int maxIndex);
    
    
    template <class T>
    
    class Matrix
    
    {
    
    public:
    
           Matrix (int nrows_ = 0, int ncols_ = 0); // ctor
    
           Matrix (const Matrix& mat_); // copy ctor
    
    
    
           ~Matrix (); // dtor
    
    
    
           Matrix& operator=(const Matrix& mat_); // assignment operator
    
    
    
           int nRows () const;    // return no. of rows
    
           int nCols () const;    // return no. of cols
    
           int nElems () const;   // return total no. of elements
    
           int isSquare () const; // is this a square matrix?
    
    
    
           // nested class for each row of the matrix
    
           class RowArray
    
           {
    
           public:
    
               // set an element value (allows write access)
    
                   T& operator [] (int col)
    
                   { checkIndex (col, ncol); return rp[col];}
    
    
    
                   // retrieve an element value (read-only)
    
                   const T& operator [] (int col) const
    
                   { checkIndex (col, ncol); return rp[col]; }
    
    
    
           private:
    
                   RowArray (T* row_, int ncol_) : rp (row_), ncol (ncol_) {}
    
                   T *rp; // row pointer
    
                   int ncol;   // no. of columns
    
    
    
                   friend class Matrix<T>;
    
           }; // end of nested class RowArray
    
    
    
           // retrieve an element value (read-only)
    
           const RowArray operator[] (int row_) const
    
           {
    
                   checkIndex (row_, nrows);
    
                   return RowArray (data[row_], ncols);
    
           }
    
    
    
       // set an element value (allows write access)
    
           RowArray operator[] (int row_)
    
           {
    
                   checkIndex (row_, nrows);
    
                   return RowArray (data[row_], ncols);
    
           }

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Is this failing when you CREATE the matrix, or when you try to use it?

    If the failure is to create the matrix, I'd like to see the matrix(int nrows, int ncols) constructor source as well.

    In the case of the create matrix succeeding, try adding a printout of the p.nRows() and p.nCols() and verify that those are indeed 605 both of them.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Apr 2008
    Posts
    12
    Quote Originally Posted by matsp View Post
    Is this failing when you CREATE the matrix, or when you try to use it?

    If the failure is to create the matrix, I'd like to see the matrix(int nrows, int ncols) constructor source as well.

    In the case of the create matrix succeeding, try adding a printout of the p.nRows() and p.nCols() and verify that those are indeed 605 both of them.

    --
    Mats
    It's failing when i'm trying to input the values into the matrix. I checked p.nRows() and p.nCols() after the function create_weight was called and both of them are 605.

    here's the constructor:

    Code:
    // constructor
    
    template <class T>
    
    Matrix<T>::Matrix (int nrows_, int ncols_)
    
    : nrows (nrows_), ncols (ncols_)
    
    { matAlloc (nrows, ncols); }

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Strange. Presuming that matAlloc simply does what it should, I would put in the following code:
    Code:
    void create_weight(Matrix<double>& P, vector<RangeRecord>& ranges, int n)
    {
      for(int i=0; i<n; i++)
      {
        for(int j=0; j<n; j++)
        {
    
          if (P.nRows() != n || P.nCols() != n)  {
             cerr << "Huh? i = " << i << " j=" << j << " nCols()=" << P.nRows() << " nCols()=" || P.nCols() << endl;
             exit(1);
          }
          if(i==j)
            P[i][i]=1/(sq(ranges[i].pseudorangeStdDev));
          else
            P[i][j]=0;
        }
      }
    }
    That way, the time when it changes, you'll see the new value and what value of i and j it is.



    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Invalid conversion from 'void*' to 'BYTE' help
    By bikr692002 in forum C++ Programming
    Replies: 9
    Last Post: 02-22-2006, 11:27 AM
  2. Learning OpenGL
    By HQSneaker in forum C++ Programming
    Replies: 7
    Last Post: 08-06-2004, 08:57 AM
  3. Very handy matrix functions - part 1
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 05-20-2004, 10:38 AM
  4. Replies: 11
    Last Post: 03-25-2003, 05:13 PM