应用介绍
Armadillo 是一个高效、易用的 C++ 数值计算库,主要用于线性代数运算,如矩阵和向量的操作。它是开源的,采用了现代 C++ 的特性,设计上与 MATLAB 或 Octave 类似,因此很容易上手,特别适合那些已经熟悉这些科学计算工具的用户。
主要特点:
线性代数功能: Armadillo 提供了丰富的线性代数功能,包括矩阵和向量的运算,矩阵分解(如 LU、QR、SVD 等),特征值计算,线性方程求解等。
高效性:库的底层使用了高效的数学库,如 LAPACK 和 BLAS,确保了运算的速度。
Armadillo 对于大规模矩阵运算进行了优化,支持多线程计算。
简洁的语法:Armadillo 的语法与 MATLAB 或 Octave 类似,因此对于有这些背景的用户来说,学习曲线较低。
提供了类似于 MATLAB 风格的运算符重载(如矩阵乘法、转置等)。
与其他库的兼容性:支持与其他科学计算库(如 LAPACK、BLAS、ARPACK、SuperLU 等)的集成。
可以与其他 C++ 库、Python、MATLAB 等接口进行互操作。
可扩展性:由于是基于 C++ 开发,Armadillo 可以灵活地扩展功能,适合在各种复杂应用中使用。
支持复杂的数据类型(如复数矩阵)和多维数组运算。
跨平台:支持多种操作系统,包括 Linux、macOS 和 Windows,且在多个平台上表现良好。
科学计算工具:除了基础的矩阵运算外,Armadillo 还提供了求解线性方程组、优化问题、统计计算等高级功能。
主要功能:
矩阵运算:包括矩阵加法、乘法、转置、逆等。
矩阵分解:支持多种分解方式,如 LU、QR、SVD、Cholesky 等。
特征值问题:可以计算特征值和特征向量。
线性方程求解:支持使用不同的算法(如 Gauss 消元法)来解线性方程组。
统计计算:提供均值、方差、协方差等常见统计量的计算。
随机数生成:内置随机数生成器,支持正态分布、均匀分布等多种分布。
加载环境
## gcc 环境变量
export PATH=/opt/app/gcc/9.5.0_gcc4.8.5/bin:$PATH
export LD_LIBRARY_PATH=/opt/app/gcc/9.5.0_gcc4.8.5/lib64:$LD_LIBRARY_PATH
export LIBRARY_PATH=/opt/app/gcc/9.5.0_gcc4.8.5/lib:/opt/app/gcc/9.5.0_gcc4.8.5/lib64:$LIBRARY_PATH
export C_INCLUDE_PATH=/opt/app/gcc/9.5.0_gcc4.8.5/include:$C_INCLUDE_PATH
export CPATH=/opt/app/gcc/9.5.0_gcc4.8.5/include:$CPATH
## armadillo 环境变量
export LD_LIBRARY_PATH=/opt/app/armadillo/14.2.2/lib64:$LD_LIBRARY_PATH
export LIBRARY_PATH=/opt/app/armadillo/14.2.2/lib64:$LIBRARY_PATH
export C_INCLUDE_PATH=/opt/app/armadillo/14.2.2/include:$C_INCLUDE_PATH
export CPATH=/opt/app/armadillo/14.2.2/include:$CPATH
## lapack 环境变量
export LD_LIBRARY_PATH=/opt/app/lapack/3.12.0/lib64/:$LD_LIBRARY_PATH
export LIBRARY_PATH=/opt/app/lapack/3.12.0/lib64/:$LIBRARY_PATH
## openblas 环境变量
export LD_LIBRARY_PATH=/opt/app/openblas/0.3.28_gcc9.5.0/lib:$LD_LIBRARY_PATH
export C_INCLUDE_PATH=/opt/app/openblas/0.3.28_gcc9.5.0/include:$C_INCLUDE_PATH
export CPATH=/opt/app/openblas/0.3.28_gcc9.5.0/include:$CPATH
使用说明
先创建一个目录armadillotest并进入该目录:
mkdir armadillotest
cd armadillotest
在该目录下创建如下测试文件armadillotest.cpp
// 对矩阵A进行PLU分解,其中P为置换矩阵,PA=LU
#include <random>
#include <algorithm>
#include <stdlib.h>
#include <iostream>
#include <ctime>
#include <armadillo>
using namespace arma;
int main()
{
int N = 5;
arma::mat A = zeros<mat>(N, N);
for (size_t i = 0; i < N; i++)
{
A(i, i) = i + 1.1;
if (i != N - 1)
{
A(i, i + 1) = i + 4.4;
A(i + 1, i) = i + 3.3;
}
if (i != N - 1 && i != N - 2)
{
A(i + 2, i) = i + 3.3;
}
}
// 定义一个permutation matrix对象p
arma::mat P;
arma::mat L;
arma::mat U;
// 使用Armadillo的lu函数进行LU分解
struct timespec start1, end1;
double duration1;
clock_gettime(CLOCK_REALTIME, &start1);
arma::lu(L, U, P, A);
clock_gettime(CLOCK_REALTIME, &end1);
duration1 = (end1.tv_sec - start1.tv_sec) + (end1.tv_nsec - start1.tv_nsec) / 1000000000.0;
printf("The time is %lf microseconds\n", duration1 * 1000);
std::cout << "A:\n"
<< A << std::endl;
std::cout << "P:\n"
<< P << std::endl;
std::cout << "L:\n"
<< L << std::endl;
std::cout << "U:\n"
<< U << std::endl;
std::cout << "L*U:\n"
<< L * U << std::endl;
std::cout << "P*A:\n"
<< P * A << std::endl;
return 0;
}
编译并执行程序
g++ armadillotest.cpp -larmadillo -o armadillotest
./armadillotest
执行结束后可看到如下结果
The time is 0.110207 microseconds
A:
1.1000 4.4000 0 0 0
3.3000 2.1000 5.4000 0 0
3.3000 4.3000 3.1000 6.4000 0
0 4.3000 5.3000 4.1000 7.4000
0 0 5.3000 6.3000 5.1000
P:
0 1.0000 0 0 0
0 0 0 1.0000 0
1.0000 0 0 0 0
0 0 1.0000 0 0
0 0 0 0 1.0000
L:
1.0000 0 0 0 0
0 1.0000 0 0 0
0.3333 0.8605 1.0000 0 0
1.0000 0.5116 0.7879 1.0000 0
0 0 -0.8333 0.4745 1.0000
U:
3.3000 2.1000 5.4000 0 0
0 4.3000 5.3000 4.1000 7.4000
0 0 -6.3605 -3.5279 -6.3674
0 0 0 7.0821 1.2311
0 0 0 0 -0.7899
L*U:
3.3000 2.1000 5.4000 0 0
0 4.3000 5.3000 4.1000 7.4000
1.1000 4.4000 0 0 0
3.3000 4.3000 3.1000 6.4000 0
0 0 5.3000 6.3000 5.1000
P*A:
3.3000 2.1000 5.4000 0 0
0 4.3000 5.3000 4.1000 7.4000
1.1000 4.4000 0 0 0
3.3000 4.3000 3.1000 6.4000 0
0 0 5.3000 6.3000 5.1000