Search code examples
c++reigen3

Eigen3: Matrix row and column names


In R, I can name the rows and columns of a matrix:

A = matrix( 
  c(2, 4, 3, 1, 5, 7), # the data elements 
  nrow=2,              # number of rows 
  ncol=3,              # number of columns 
  byrow = TRUE)        # fill matrix by rows 

> A                      # print the matrix 

      [,1] [,2] [,3] 
[1,]    2    4    3 
[2,]    1    5    7 

dimnames(A) = list( 
  c("row1", "row2"),         # row names 
  c("col1", "col2", "col3")) # column names

> A                 # print A 
     col1 col2 col3 
row1    2    4    3 
row2    1    5    7 

How do I give row and column names to an Eigen3 Matrix from c++?


Solution

  • What I did since it doesn't appear that Eigen supports column and row names is to hash it myself. More typing to get it going, but does the job.

    namespace EigenRCNames
    {
    // The key in my case is a string, but it could be a tuple
    //typedef std::tuple<std::string, std::string> rc_key_t;
    typedef std::string rc_key_t;
    
    struct key_hash : public std::unary_function<currency_key_t, std::size_t>
    {
        std::size_t operator()(const rc_key_t& k) const
        {
            std::hash<std::string> hash_fn;
    
            return hash_fn(k);
        }
    };
    
    struct key_equal : public std::binary_function<rc_key_t, rc_key_t, bool>
    {
        bool operator()(c rc_key_t& v0, const  rc_key_t& v1) const
        {
            return (v0 == v1);
        }
    };
    
    struct data
    {
        int row;
        int column;
    
        inline bool operator ==(data d)
        {
           if (d.row == row && d.column == column)
              return true;
           else
              return false;
        }
    
        friend std::ostream& operator << (std::ostream& os, const data& rhs)    //Overloaded operator for '<<'
        {                                                                       //for struct output
            os  << rhs.row << ", "
                << rhs.column;
    
            return os;
        }
    };
    
    typedef std::unordered_map<const  rc_key_t, data, key_hash, key_equal> map_t;
    //                                                     ^ this is our custom hash
    
    }
    

    Then,

    //Row STRAWBERRY and Column BANANA maps to {0,0}
    static std::string STRAWBERRYBANANA = "STRAWBERRY-BANANA";
    data dSTRAWBERRYBANANA = {0, 0};
    
    static map_t m;
    
    m[STRAWBERRYBANANA] = dSTRAWBERRYBANANA;
    

    And then searching by key "STRAWBERRY-BANANA" or value {0, 0} is straigthforward.