【问题标题】:Matlab type arrays in C++C ++中的Matlab类型数组
【发布时间】:2012-07-28 21:04:10
【问题描述】:

如何像在 matlab 中一样在 C++/Open CV 中定义数组?

例如:

x=a:b:c;

y=linspace(a,b,n);

【问题讨论】:

  • 类似问题的好答案here

标签: c++ arrays matlab opencv


【解决方案1】:

我想对 mattgately 提出的代码稍加修改。我使用了它,在某些情况下 step 由于除法近似而无法正确计算

double step = (b-a) / (n-1);

我只是在while 条件中添加了一个小数:

while(a <= b+0.00001)

就像这样,它对我有用,并创建了正确数量的间隔。

【讨论】:

    【解决方案2】:

    @Gilad 对于n=0n=1 的答案的扩展,因为后者会导致除以零。

    vector<double> linspace(double a, double b, int n) {
        vector<double> array;
        if ((n == 0) || (n == 1) || (a == b))
            array.push_back(b);
        else if (n > 1) {
            double step = (b - a) / (n - 1);
            int count = 0;
            while(count < n) {
                array.push_back(a + count*step);
                ++count;
            }
        }
        return array;
    }
    

    【讨论】:

    • 您的代码无法处理 step 为 -ve 的情况。 (b>a 或 b
    • @ankittie 是什么让你这么说,你试过代码吗? step 属于 double 类型,可以是 +ve 或 -ve。
    【解决方案3】:

    这是我测试过的 linspace,与所有其他的非常相似,但可以处理所有情况:

    vector<double> Utilities::Linspace(double a, double b, int n) {
        vector<double> array;
        double epsilon = 0.0001;
        double step = (b-a) / (n-1);
        if (a==b)
        {
            for (int i = 0; i < n; i++)
            {
                array.push_back(a);
            }
        }
        else if (step >= 0)
        {
            while(a <= b + epsilon)
            {
                array.push_back(a);
                a += step;           
            }       
        }
        else
        {
            while(a + epsilon >= b )
            {
                array.push_back(a);
                a += step;           
            }       
        }
        return array;
    }
    

    【讨论】:

    • n=1时被零除的经典错误...我发布了一些细微的变化(见下文)
    【解决方案4】:
    double* linspace(int xi, int xf, unsigned int n){
    double *vec ;
    vec = new double[n];
    float esp, falt=xf-xi;
    esp=falt/(n-1);
    vec[0]=xi;
    for(int i=1; i<n; i++)
        vec[i]=vec[i-1]+esp;
    return vec;
    

    【讨论】:

    • 你的答案应该包含对你的代码的解释和它如何解决问题的描述。
    【解决方案5】:

    如果你使用 openCV,这是一个简单的实现。

    Mat linspace(double &startP,double &Endp,int &interval)
    {
        double spacing = interval-1;
        Mat y(spacing,1,CV_64FC1);
        for (int i = 0; i < y.rows; ++i)
        {
            y.at<double>(i) = startP + i*(Endp - startP)/spacing;
        }
        return y;
    }
    

    【讨论】:

      【解决方案6】:

      有关您问题的一般答案,请参阅之前的答案。

      具体来说,为了解决您提到的两个示例,这里有一些等效的 c++ 代码,使用向量来动态生成您提到的数组(尚未测试):

      #include <vector>
      using std::vector;
      
      vector<double> generateRange(double a, double b, double c) {
          vector<double> array;
          while(a <= c) {
              array.push_back(a);
              a += b;         // could recode to better handle rounding errors
          }
          return array;
      }
      
      vector<double> linspace(double a, double b, int n) {
          vector<double> array;
          double step = (b-a) / (n-1);
      
          while(a <= b) {
              array.push_back(a);
              a += step;           // could recode to better handle rounding errors
          }
          return array;
      }
      

      【讨论】:

      • 预分配用n 值填充array,然后push_back 将大约n 值附加到末尾,所以你应该放弃预分配
      • 感谢@YuppieNetworking。我混淆了语言,认为构造函数分配没有填充。我删除了预分配,因为使用了push_back
      • @mattgately,你可以使用reserve函数更有效。
      【解决方案7】:

      不幸的是,C++ 没有内置任何东西来允许这种矩阵初始化。它支持多维数组,但您需要自己初始化每个元素。 C++ 是一种比 Matlab 低级的语言,它涉及更多的工作来编写创建和初始化矩阵类型变量的功能。

      话虽如此,有许多库可与 C++ 一起使用,它们使数值计算比您自己尝试编写它更容易。如果您需要考虑使用库,请查看此链接,其中建议了一些合适的 https://scicomp.stackexchange.com/questions/351/recommendations-for-a-usable-fast-c-matrix-library

      【讨论】:

        【解决方案8】:

        OpenCV 提供了一些类似于 Matlab 的功能,但数量非常有限。

        你可以

        cv::Mat a = cv::Mat::eye(5);
        cv::Mat b = cv::Mat::zeros(5);
        cv::Mat img = cv::imread("myGorgeousPic.jpg");
        cv::imwrite(img, "aCopyOfMyGorgeousPic.jpg");
        

        还支持diag()

        但是对于大多数棘手的 Matlab 功能,如 linspacemagic 或其他任何东西,OpenCV 中没有对应的,主要是因为 OpenCV 不是数学包,而是计算机视觉包。如果你需要一些特定的功能,你可以在你的项目中克隆它(也就是你自己写的)

        【讨论】:

          猜你喜欢
          • 2010-10-20
          • 2012-11-05
          • 2014-08-03
          • 1970-01-01
          • 2013-05-05
          • 2021-07-18
          • 2011-12-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多