Eigen教程(三)-The Array Class And Coefficient-Wise Operations

Array类提供了多用途的数组,这与专门为线性代数设计的Matrix类相反,此外,Array类提供了方便的元素级操作,这些操作不具线性代数的意义,比如为数组每个元素加上一个常数或对两个数组的对应元素进行相乘。

1.Array Types

Array是一个类模板,其模板参数与Matrix类一致,前三个参数仍是必须的:

Array<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>

后三个参数是可选的,不做过多解释,参照Matrix类即可。

Eigen也为一些常见的Array类型提供了简便的typedefs,与Matrix的typedefs相似,但稍微不同,因为Array可同时用于一维、二维数组,因此我们规定ArrayNt的形式代表一维数组,其中 N 、 t N、t Nt分别代表长度数据类型,对于二维数组我们用ArrayNNt,以下是一些例子:

typedef Array<float,Dynamic,1> ArrayXf 
typedef Array<float,3,1> Array3f 
typedef Array<double,Dynamic,Dynamic> ArrayXXd 
typedef Array<double,3,3> Array33d 

2.Accessing Values Inside An Array

Matrix类一致,括号运算符()已经被重载,以对Array类元素进行读写操作,此外,<<操作符可用于初始化数组或对数组进行打印

#include <Eigen/Dense>
#include <iostream>
 
using namespace Eigen;
using namespace std;
 
int main()
{
  ArrayXXf  m(2,2);
  
  // assign some values coefficient by coefficient
  m(0,0) = 1.0; m(0,1) = 2.0;
  m(1,0) = 3.0; m(1,1) = m(0,1) + m(1,0);
  
  // print values to standard output
  cout << m << endl << endl;
 
  // using the comma-initializer is also allowed
  m << 1.0,2.0,
       3.0,4.0;
     
  // print values to standard output
  cout << m << endl;
}

输出如下:

1 2
3 5

1 2
3 4

3.Addition And Subtraction

对两个数组进行的加减与对矩阵加减一致,只要两个数组尺寸一致,加减操作就是合法的,并且加减都是元素级的操作,会对数组对应位置的两个元素进行加减并得到新的数组。

数组同时支持如Array + Scalar的形式,此操作会将标量与数组中的每个元素进行相加,这种功能在Matrix类中并不能直接进行实现:

#include <Eigen/Dense>
#include <iostream>
 
using namespace Eigen;
using namespace std;
 
int main()
{
  ArrayXXf a(3,3);
  ArrayXXf b(3,3);
  a << 1,2,3,
       4,5,6,
       7,8,9;
  b << 1,2,3,
       1,2,3,
       1,2,3;
       
  // Adding two arrays
  cout << "a + b = " << endl << a + b << endl << endl;
 
  // Subtracting a scalar from an array
  cout << "a - 2 = " << endl << a - 2 << endl;
}

输出如下:

a + b = 
 2  4  6
 5  7  9
 8 10 12

a - 2 = 
-1  0  1
 2  3  4
 5  6  7

4.Array Multiplication

首先,你完全可以使用标量与数组相乘,这与矩阵是一样的。但当你用数组与数组相乘时,ArrayMatrix的区别就体现出来了:矩阵将乘法理解成矩阵乘法而数组将乘法理解成对应元素相乘,因此两个数组能够相乘的条件是它们有同样的大小:

#include <Eigen/Dense>
#include <iostream>
 
using namespace Eigen;
using namespace std;
 
int main()
{
  ArrayXXf a(2,2);
  ArrayXXf b(2,2);
  a << 1,2,
       3,4;
  b << 5,6,
       7,8;
  cout << "a * b = " << endl << a * b << endl;
}

输出如下:

a * b = 
 5 12
21 32

5.Other Coefficient-Wise Operations

除了上述提到的加、减、乘之外,Array类还定义了其他元素级运算,如:.abs()取每个元素的绝对值,.sqrt()计算每个元素的平方根;如果有两个相同尺寸的数组,你还可以调用.min(.)构造一个数组,数组中每个元素是所提供的两个数组中对应位置最小的那个元素:

#include <Eigen/Dense>
#include <iostream>
 
using namespace Eigen;
using namespace std;
 
int main()
{
  ArrayXf a = ArrayXf::Random(5);
  a *= 2;
  cout << "a =" << endl 
       << a << endl;
  cout << "a.abs() =" << endl 
       << a.abs() << endl;
  cout << "a.abs().sqrt() =" << endl 
       << a.abs().sqrt() << endl;
  cout << "a.min(a.abs().sqrt()) =" << endl 
       << a.min(a.abs().sqrt()) << endl;
}

输出如下:

a =
    -2
 -1.47
  1.02
-0.165
 0.131
a.abs() =
    2
 1.47
 1.02
0.165
0.131
a.abs().sqrt() =
 1.41
 1.21
 1.01
0.407
0.362
a.min(a.abs().sqrt()) =
    -2
 -1.47
  1.01
-0.165
 0.131

6.Converting Between Array And Matrix Expressions

Eigen不允许对数组进行矩阵操作,也不允许对矩阵进行数组操作,因此当你同时需要用到到两种操作时,你需要将一个矩阵转换成数组或将数组转换成矩阵,以下提供了一些方法使得两种类型的操作可以作用于同一个对象(不管将其声明为数组或是矩阵)。

Matrix表达式中的.array()方法可将矩阵‘转换’为数组,使得元素级操作变得简便;相反,Array中的.matrix()方法实现相反的‘转换’,.array().matrix()都能作为左值和右值。

官网废话太多了,总结几点:

  • 可以将一个数组变量赋值给矩阵变量,反之亦然
  • 矩阵元素级乘法除了用.array()转换为数组外还有const .cwiseProduct(.)

直接上例子:

	MatrixXf m(2, 2);
    MatrixXf n(2, 2);
    // All Matrix and Array class variables can be assigned by Matrix or Array expression
    // MatrixXf result(2, 2);
    ArrayXXf result(2, 2);
    m << 1, 2, 
         3, 4;
    n << 5, 6, 
         7, 8;
    result = m * n;
    cout << "-- matrix m * n --" << endl << result << endl << endl;
    result = m.array() * n.array();
    cout << "-- array m * n --" << endl << result << endl << endl;
    result = m.cwiseProduct(n);
    cout << "-- with cwiseProduct --" << endl << result << endl << endl;
    result = m.array() + 4;
    cout << "-- array m + 4 --" << endl << result << endl << endl;

输出如下:

-- Matrix m*n: --
19 22
43 50

-- Array m*n: --
 5 12
21 32

-- With cwiseProduct: --
 5 12
21 32

-- Array m + 4: --
5 6
7 8

下面是一个更高级用法的例子(实际就是复合操作):

#include <Eigen/Dense>
#include <iostream>
 
using namespace Eigen;
using namespace std;
 
int main()
{
  MatrixXf m(2,2);
  MatrixXf n(2,2);
  MatrixXf result(2,2);
 
  m << 1,2,
       3,4;
  n << 5,6,
       7,8;
  
  result = (m.array() + 4).matrix() * m;
  cout << "-- Combination 1: --" << endl << result << endl << endl;
  result = (m.array() * n.array()).matrix() * m;
  cout << "-- Combination 2: --" << endl << result << endl << endl;
}

输出如下:

-- Combination 1: --
23 34
31 46

-- Combination 2: --
 41  58
117 170
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sure, here is a Python implementation of the QR algorithm for computing the Eigen-Decomposition of a given matrix. The algorithm is iterative and works by repeatedly applying the QR decomposition to the matrix until it converges to a diagonal matrix. ```python import numpy as np def qr_algorithm(A, eps=1e-8, max_iter=1000): """ Compute the Eigen-Decomposition of a given matrix using the QR algorithm :param A: the input matrix :param eps: the tolerance for convergence :param max_iter: the maximum number of iterations :return: the eigenvalues and eigenvectors of the input matrix """ n = A.shape[0] Q = np.eye(n) for i in range(max_iter): Q_, R = np.linalg.qr(A.dot(Q)) Q = Q.dot(Q_) A = R.dot(Q) if np.abs(A - np.diag(np.diag(A))).max() < eps: break return np.diag(A), Q ``` In this implementation, we start with an identity matrix Q and repeatedly apply the QR decomposition to the matrix A, until it converges to a diagonal matrix. We check for convergence by comparing the off-diagonal elements of the matrix A with a tolerance of eps. If the off-diagonal elements are smaller than eps, we break out of the loop and return the diagonal elements of A as the eigenvalues of the input matrix and the columns of Q as the eigenvectors. Note that this implementation assumes that the input matrix A is real and symmetric. If the matrix is not symmetric, we can use the Hessenberg reduction to transform it into a similar matrix that is upper Hessenberg, which can then be used as input to the QR algorithm.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值