【问题标题】:How can I return an array of matrices of differing sizes in c++?如何在 C++ 中返回不同大小的矩阵数组?
【发布时间】:2017-11-18 00:31:39
【问题描述】:

我的c++还不是很高级,但我正在尝试进行聚类分析,

数据,向量> X,是 M x T,具有 M 个特征和 T 个数据点,我试图将特征分组到集合中,其中集合中每个特征之间的距离相关性高于某个阈值。顺便说一句,distCorrelation 函数已经定义好了。

set<vector<double>> clusterIndices(vector<vector<double>> &X, double threshold){
    vector<double> feature[X.size()];
    for(int i = 0; i < X.size(); i++){
        for(int j = 0; j < X[0].size(); j++){
            feature[i].push_back(X[i][j]);
        }
    }
    vector<vector<double>> distCorrMatrix(X.size(), vector<double> (X.size()));
    for (int i = 0; i < X.size(); i++){
        for (int j = 0; j < X.size(); j++){
            distCorrMatrix[i][j] = (distCorrelation(feature[i],feature[j]) >= threshold ? 1.0 : 0.0);
        }
    }
    set<vector<double>> rows;
    for (int i = 0; i < X.size(); i++){
        vector<int> temp;
        for (int j = 0; j < X.size(); j++){
            if (distCorrMatrix[i][j] == 1){
                temp.push_back(j);
            }
        }
        rows.insert(temp);
    }
    return rows;
}

所以上面的代码将产生相互高度相关的特征集,但只会给出这些特征的索引。 也就是说,返回的行可能是 (1,2,5) , (3,7,8,10) ... 等转换为 (feature[1],feature[2],feature[5]) , (特征[3],特征[7],特征[8],特征[10]) ...等其中特征[i]代表数据矩阵的第i行。

问题是我不知道如何创建一个函数,将每个集合转换为矩阵并返回它们。

【问题讨论】:

  • vector&lt;vector&lt;double&gt;&gt; 中包含的每个 vector&lt;double&gt; 可以有不同的大小。除此之外,不清楚你在问什么。
  • 我会得到/制作一个矩阵类型,然后你就可以拥有该矩阵类型的向量。
  • 结果应该是什么样的?您采用单个(2D)矩阵并想要返回一个矩阵数组(即一个类似 3 维数组)?这似乎很可疑......
  • 他采用 2D 矩阵,例如 100 列和 3 行(3D 空间中的点)。它们分为三个集群,因此他想返回 3 个矩阵(40 列之一、25 列之一和 35 列之一)来表示集群。

标签: c++ function vector return return-type


【解决方案1】:

据我所知,你想要这个

std::vector<int> myclusteringfunction(std::vector<std::vector<double> > const &dataitems)
{
   /* assign a cluster id to each data item */
   std::vector<int> answer;
   for(i=0;i<dataitems.size();i++)
       answer.push_back( /* get the cluster id for each data item */);

   /* return the ids as a list of the same length as your input list
      eg {0, 1, 2, 1, 1, 1, 2, 2, 0, 0, 3, 1, 1, 1, 1} for four clusters */

   return answer;
}

【讨论】:

    【解决方案2】:

    您的输入似乎不清楚,但我们可以这样:(检查函数 getVectorOfMatrices)

    #include <vector>
    #include <iostream>
    
    /**
     * A classic 2D matrix implementation. 
     * Pay attention to the constructors and the operator=.
     */
    class Matrix2D {
    public:
       // Standard constructor, allocates memory and initializes.
       Matrix2D(const unsigned int rows, const unsigned int columns) 
                                  : m_rows(rows), m_columns(columns) {
         m_data = new float*[rows];
         for(unsigned row = 0; row < rows; ++row) {
           m_data[row] = new float[columns];
           for (unsigned column = 0; column < columns; ++column) {
             m_data[row][column] = 0;
           }
         }
       }
    
       // Copy-constructor - also allocates and initializes.
       Matrix2D(const Matrix2D& rhs) {
          m_rows = rhs.m_rows;
          m_columns = rhs.m_columns;
          m_data = new float*[rhs.m_rows];
          for (unsigned row = 0; row < rhs.m_rows; ++row) {
             m_data[row] = new float[rhs.m_columns];
             for (unsigned column = 0; column < rhs.m_columns; ++column) {
               m_data[row][column] = rhs.at(row, column);
             }
          }
       }
    
       // Affectation operator - also allocates memory and initializes.
       Matrix2D& operator=(const Matrix2D& rhs) {
          m_rows = rhs.m_rows;
          m_columns = rhs.m_columns;
          m_data = new float*[rhs.m_rows];
          for (unsigned row = 0; row < rhs.m_rows; ++row) {
             m_data[row] = new float[rhs.m_columns];
             for (unsigned column = 0; column < rhs.m_columns; ++column) {
               m_data[row][column] = rhs.at(row, column);
             }
          }
       }
    
       // Used to set values in the 2D matrix 
       // NOTA : This function should check row vs m_rows and column vs m_columns
       float& at(const unsigned int row, const unsigned int column) {
         return m_data[row][column];
       }
    
       // Used to get values of the 2D matrix
       // NOTA : This function should check row vs m_rows and column vs m_columns
       const float at(const unsigned int row, const unsigned int column) const {
         return m_data[row][column];
       }
    
       // Debug tool - prints the matrix
       void print() const {
         for (unsigned row = 0; row < m_rows; ++row) {
           for (unsigned column = 0; column < m_columns; ++column) {
             std::cout << " " << m_data[row][column] << " ";
           }
           std::cout << std::endl;
         }
       }
    
       // Destructor - deallocates the memory
       ~Matrix2D() {
         for (unsigned int row=0; row<m_rows; ++row) {
           delete[] m_data[row];
         }
         delete[] m_data;
       }
    
    private:
       unsigned int m_rows; // y-size
       unsigned int m_columns; // x-size
       float**  m_data; // the data
    };
    
    /*
     * Function that creates and returns a vector of 2D matrices 
     * Matrices are of different sizes
     */
    std::vector<Matrix2D> getVectorOfMatrices() {
       Matrix2D m1(1,1);
       Matrix2D m2(2,2);
       Matrix2D m3(3,3);
       Matrix2D m4(4,2);
    
    
       m1.at(0, 0) = 4;
       m2.at(0, 1) = 2;
       m4.at(1, 1) = 8;
    
       std::vector<Matrix2D> result;
    
       result.push_back(m1);
       result.push_back(m2);
       result.push_back(m3);
       result.push_back(m4);
       return result;
    }
    
    /*
     * Main - simply call our function.
     */
    int main () {
      std::vector<Matrix2D> vec = getVectorOfMatrices();
      for(std::vector<Matrix2D>::iterator it = vec.begin(); it != vec.end(); ++it) {
        it->print();
      }
      return 0;
    }
    

    【讨论】:

      【解决方案3】:

      不,您的代码不会编译。你应该这样做:

      // k is the number of clusters
      vector<vector<vector<double> > > myFunction(vector<vector<double> > &X, int k) {
          vector<vector<vector<double> > > result(k);
          for (int i = 0; i < X.size(); i++){
              //do something then know X[i] belongs to cluster j
              result[j].push_back(X[i]);
          }
          return result;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-14
        相关资源
        最近更新 更多