在c++中创建带状矩阵

Creating a Banded Matrix in C++

本文关键字:创建 c++      更新时间:2023-10-16

我正试图转换创建带状对角矩阵的Matlab代码。我试图转换的Matlab代码是:

N = 5;
e = ones(N-1, 1);
D = spdiags([-e 2*e -e], [-1 0 1], N-1, N-1);
D = full(D);

上述Matlab代码的输出,D =

 2    -1     0     0
-1     2    -1     0
 0    -1     2    -1
 0     0    -1     2

我在c++中最接近的转换方法是:

#include<iostream>
#include<vector>
using namespace std;
vector< vector<double> > bandedMat(vector<double> &e,int N);
int main()
{
   int N = 5 ;
   vector<double> e = {-1,2,-1};
   vector< vector<double> > B = bandedMat(e,N);
   return 0;
}
vector< vector<double> > bandedMat(vector<double> &e,int N)
{
   vector< vector<double> > D(N-2, vector<double>(N,0.0));
   double val = 0.0;
  for(int i = 0; i < D.size(); i++)
  {
     for(int j = 0; j < e.size(); j++)
     {
        val = e[j];
        D[i][i+j] = val; // Put along the diagonal of matrix D. Note the    index.
     }
  }
  return D;
}
下面c++代码的输出是D=
-1  2 -1  0  0
0  -1  2 -1  0
0  0  -1  2 -1 

正如你所看到的,我的c++版本是完全不同的,它产生的D是3x5,而不是Matlab版本产生的D是4 x 4。另外,我的c++版本的对角线有一点不同。有人能指出我怎么能得到确切的D像Matlab版本。

虽然我认为它不优雅,但至少它现在解决了我的问题。

vector< vector<double> > bandedMat(vector<double> &e,int N)
{
    // Do some checking, Only tridiagonals are allowed.
    if(e.size()>3)
    {
        cout << "Only tridiagonals are allowed. Input vector to function must be only 3 elements." << endl;
        exit(EXIT_FAILURE);
    }
    vector< vector<double> > D(N-1, vector<double>(N-1,0.0));
    for(size_t i = 0; i < D.size(); i++)
    {
        for(size_t j = 0; j < D.size(); j++)
        {
            if(i == j)
            {
                D[i][j] = e[1]; // put value of e[1] as the main diagonal of D
            }
        }
    }
    int j =0; // index
    int k =0; // index
    for(size_t i =0; i < D.size()-1;i++)
    {
        D[i][j+1] = e[0]; // put value e[0] as the upper diagonal
        j = j+1;
    }
    for(size_t i =0; i < D.size()-1;i++)
    {
        D[i+1][k] = e[2]; // put value of e[2] as the lower diagonal
        k = k+1;
    }
    return D;
}

将生成与Matlab版本类似的精确矩阵。如果有人有更好的想法或更优雅的方法,请分享。谢谢。

稍显优雅…你可以把这三个元素放到一个循环中

for(size_t i = 0; i < D.size(); i++)
{
    if (i<D.size()) {
        D[i][i+1] = e[0];
    }
    D[i][i] = e[1]; // put value of e[1] as the main diagonal of D
    if (i>0) {
        D[i][i-1] = e[2];
    }
}