- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试执行 Armadillo c++ 库中的 expmat() 函数,但是当我运行它时它会被堆叠起来。首先,我在 Matlab 中尝试使用 expm 函数,并在 C++ 程序中使用不同的值,它在两种情况下都有效。所以,问题出在与我放在矩阵上的值相关的东西上,似乎其中一些太小了......这是我想要计算指数的 [14x14] 平方矩阵:
mat A;
A << 0 << -0.0000769006 << -0.0000511322 << -0.0000915495 << 0 << 0 << -0.00254523 << 0.00000001 << 0 << 0 << 0 << 0 << 0 << 0 << endr
<< 0.0000769006 << 0 << 0.0000915495 << -0.0000511322 << 0.0043037 << -0.00254523 << 0 << 0 << 0.00000001 << 0 << 0 << 0 << 0 << 0 << endr
<< 0.0000511322 << -0.0000915495 << 0 << 0.0000769006 << 0.00254523 << 0.0043037 << 0 << 0 << 0 << 0.00000001 << 0 << 0 << 0 << 0 << endr
<< 0.0000915495 << 0.0000511322 << -7.69006/100000 << 0 << 0 << 0 << 0.0043037 << 0 << 0 << 0 << 0.00000001 << 0 << 0 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0.00000001 << 0 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0.00000001 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0.00000001 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << -0.0000769006 << -0.0000511322 << -0.0000915495 << 0 << 0 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0.0000769006 << 0 << 0.0000915495 << -0.0000511322 << 0 << 0 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0.0000511322 << -0.0000915495<< 0 << 0.0000769006 << 0 << 0 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0.0000915495 << 0.0000511322 << -0.0000769006 << 0 << 0 << 0 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << -0.0043037 << -0.00254523 << 0 << 0 << 0 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0.00254523 << -0.0043037 << 0 << 0 << 0 << 0 << endr
<< 0 << 0 << 0 << 0 << 0 << 0 << 0 << 0.00254523 << 0 << 0 << -0.0043037 << 0 << 0 << 0 << endr;
B = expmat(A);
当我在调试中按下暂停键时,我看到正在执行的行是:
arma_fortran(arma_dgemm)(transA, transB, m, n, k, (const T*)alpha, (const T*)A, ldA, (const T*)B, ldB, (const T*)beta, (T*)C, ldC);
...在文件“blas_wrapper.hpp”中。没有显示错误,只有程序在那里,但它不会前进。如果我在矩阵上使用不同的值,我可以让它工作,但是我显示的那些值不......
关于LAPACK版本我不知道怎么查...
谢谢,
AV9
最佳答案
事实上,任何具有小于 1 的无限范数的矩阵都可能触发某种近乎无限的循环。问题不是来自您的代码,而是来自库。
以下由 g++ main.cpp -o main -larmadillo
编译的代码重现了这个问题:
#include <iostream>
#include <cstdio>
#include <armadillo>
using namespace std;
using namespace arma;
int
main( int argc, char* argv[] )
{
cout<<"start"<<endl;
mat A=randu(2,2);
A=A/100;
cout<<"A is "<<endl<<A<<endl;
double norm_val = norm(A, "inf");
double log2_val = eop_aux::log2(norm_val);
const uword s = (std::max)(uword(0), uword(log2_val) + uword(1) + uword(1));
cout<<"norm inf is "<<norm_val<<" log of norm inf is "<<log2_val <<" uword "<<uword(log2_val)<<" nb it is "<<s<<endl;
mat B = expmat(A);
cout<<"B is "<<endl<<B<<endl;
cout<<"end"<<endl;
}
这就是为什么......
Armadillo 引用了以下文章来计算矩阵的指数:Nineteen Dubious Ways to Compute the Exponential of a Matrix, Twenty-Five Years Later由 C. Moler 和 C. Van Loan 在 SIAM Review 中发表,2003 年。第三种方法称为“缩放和平方”,由 Armadillo 图书馆实现。使用以下公式:
m
应该足够大,以便降低 A/m
的范数并缓解 A/m
的泰勒级数指数化.
算法如下:
s
使得A/2^s
的无限范数小于1mat AA=A/2^s
e^(AA)
e^(AA)
s
次求平方来计算 e^(A)
在库 Armadillo 的文件 armadillo-4.550.3/include/armadillo_bits/op_expmat_meat.hpp
中,s
的计算方式如下:
double norm_val = norm(A, "inf");
double log2_val = eop_aux::log2(norm_val);
const uword s = (std::max)(uword(0), uword(log2_val) + uword(1) + uword(1));
如果 A 的无限范数小于 1,则 log2_val
为负,将其转换为 uword
(u 代表无符号)失败。它导致 s
非常大(例如 4294967291),并且在执行平方时代码陷入几乎无限循环。
应将测试添加到库中,在文件 armadillo-4.550.3/include/armadillo_bits/op_expmat_meat.hpp
中,类似于:
uword s=42;
if(log2_val<0){
//no need to use the formula, use Taylor series
s=0;
}else{
//need to decrease A and use the formula
s=uword(log2_val)+2;
}
代替:
const uword s = (std::max)(uword(0), uword(log2_val) + uword(1) + uword(1));
更改文件 op_expmat_meat.hpp
,通过键入 cmake 重新安装 Armadillo 。
make
和 make install
(或 sudo make install
) 问题就会消失。新的结果似乎是正确的。如果 A 接近 0:
我将通过电子邮件将此错误报告给 Armadillo 的开发人员。编辑:不需要这样做:正如@mtall 所注意到的,此问题已在版本 4.550.4 中删除。我的猜测是开发人员已经看到了您的帖子。几个小时前修改了补丁版本:开发人员的团队 react 迅速!
关于c++ - Armadillo C++ expmat 堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27591868/
在许多网站上,他们谈论 Armadillo +其他东西。它们是什么意思? 我以以下形式使用 Armadillo 库 #include 在 Linux 环境中。 在这个网站上 http://nghia
尽管成功捕获了异常,但是运行以下代码仍然会生成一条错误消息,该消息将发送到stdout(不是stderr): Mat matrix_quantiles(const vector & quantiles
我需要将 Armadillo (当前版本为 5.100.1)作为 $HOME 中的本地库(集群应用程序,不能安装在每个计算节点上,但 $HOME 是共享文件夹)。我正在使用 cmake 来管理应用程序
如何在 Armadillo C++ 中获取非零位置(索引)数组和稀疏矩阵的值? 到目前为止,我可以轻松地构造一个具有一组位置(作为 umat 对象)和值(作为 vec 对象)的稀疏矩阵: // bat
NLopt 目标函数如下所示: double myfunc(const std::vector &x, std::vector &grad, void *my_func_data) x 是被优化的数据
我想将一个 numpy 数组发送到 Armadillo (C++) 并从 C++ 程序输出一个 numpy 数组。我没有在网上找到任何教程。有人可以指点我如何做到这一点吗? 最佳答案 您可以依靠 cy
我正在尝试使用 OpenMP 并行化一个 for 循环,它对 Armadillo 矩阵求和。我有以下代码: #include #include int main() { arma:
尽管已成功捕获异常,但运行以下代码仍会产生一条错误消息,该消息会转到 stdout(而非 stderr): Mat matrix_quantiles(const vector & quantiles,
我喜欢使用 Armadillo Linear Algebra Library .当将 Octave .m 文件移植到 C++ 时,它变得非常好,尤其是当您必须使用特征方法时。 然而,当我不得不从我的原
如何实现一个简单的合并函数来合并两个矩阵,每个矩阵都有两列和一个公共(public)列 x使用 Armadillo ?换句话说,我想要一个函数 my_merge_cpp(mat1, mat2)这将使用
我正在尝试使用 Armadillo 将由整数(即 arma::Mat )组成的矩阵分解为特征值和特征向量 但是,无论我将什么作为输入矩阵和输出 vector/矩阵类型,它总是会给我编译错误 当我将输入
我有一种方法可以在使用 Armadillo 的原子中使用脚本编译c++文件?我找不到任何与此相关的信息。 我已经安装了 Armadillo ,并尝试使用原子脚本编写一些基本代码: #include
我在 cygwin64(或 minGW)下使用 Armadillo 包(v.7.300.1)生成一个随机矩阵: #include int main(){ arma::mat(3,3, arma::
我目前正在 Visual Studio 环境中使用 Armadillo 在 BeagleBone Black 上进行交叉编译,以将 MATLAB 代码转换为 C++。 这是一个信号处理项目,所以我需要
我是 Armadillo 的新手。我有以下代码,我认为它效率低下。有什么建议可以提高内存效率和/或速度吗?关注armadillo docs和 Rcpp gallery ,我无法获得 .colptr的,
如何提高 Armadillo 复杂矩阵乘法结果的精度。它近似于小数点后 4 位 [这是结果的一个示例 (35.9682,-150.246) ] 但我想要至少 8 位小数的精度。谢谢 最佳答案 因为你似
假设我有一个稀疏矩阵。我将其定义为以下 CSV 格式: 行、列、值 1,1,5 1,2,10 在这种情况下,点 (1,1) 等于 5,点 (1,2) 等于 10。 从这种格式(假设有数千或数十万行)创
我在一个项目中使用 Armadillo ,总的来说它运行良好。该项目是基于 Xcode 的,到目前为止,我设法让它工作的唯一方法是(添加/usr/include/的 header 搜索路径似乎不起作用
在 C++ 中对 vector 或矩阵执行模运算符的最佳方法是什么 Armadillo ? vector 和矩阵类重载 % 运算符以执行逐元素乘法。尝试使用它会产生 invalid operands
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Precision of multiplication by 1.0 and int float conv
我是一名优秀的程序员,十分优秀!