提升间隔矩阵
Matrices of boost intervals
我正在尝试使用区间算法为 R^n->R^m 函数编写 "divide and conquer" 根估计算法。我以前在 python 做过这个,但是性能太慢所以我决定试试 C++,我是一个初学者。
我搜索了一段时间,找到了 Boosts interval library,它似乎可以方便地解决我的问题。但是,我需要用这种间隔的矩阵进行计算。因为稍后我需要使用区间中点矩阵并(伪)反转它们,所以我认为 Eigen
可能是表示我的矩阵的好方法。
我的问题:这种方法真的是个好主意,尤其是在性能方面?如果是这样,我将如何继续使这样的矩阵能够包含间隔作为条目并使用基本操作(矩阵乘法等)
我希望能够做的事的一个例子:
#include <eigen3/Eigen/Dense>
#include <boost/numeric/interval.hpp>
using Eigen::MatrixXd;
using Eigen::VectorXd;
int main()
{
MatrixXd m(2,2);
VectorXd v(2);
Interval i1(0.0, 1.0);
Interval i2(1.0, 2.0);
Interval i3(0.0, 0.0);
m(0,0) = i1;
m(1,0) = i3;
m(0,1) = i3;
m(1,1) = i1;
v(0) = i1;
v(1) = i2;
std::cout << m*v << std::endl;
}
我对区间类型做的规范是
typedef boost::numeric::interval<double, boost::numeric::interval_lib::policies
<boost::numeric::interval_lib::save_state
<boost::numeric::interval_lib::rounded_transc_std<double> >,
boost::numeric::interval_lib::checking_base<double> > > Interval;
这最终应该输出类似 (0.0,1.0), (0.0,2.0) 的内容。现在这会引发错误 "Assigning scalar to incomparible type Interval",我不知道如何解决它,因为 Eigens 矩阵类型自然不支持间隔作为条目。
assigning to 'Scalar' (aka 'double') from incompatible type 'Interval'
(aka 'interval < double, boost::numeric::interval_lib::policies <
boost::numeric::interval_lib::save_state <
boost::numeric::interval_lib::rounded_transc_std < double > >,
boost::numeric::interval_lib::checking_base<double> > >')
欢迎任何(新手级!)参考和建议。
Docs say 那
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
这里有一些修复:
#include <boost/numeric/interval.hpp>
#include <boost/numeric/interval/utility.hpp>
#include <boost/numeric/interval/io.hpp>
namespace bn = boost::numeric;
namespace bi = bn::interval_lib;
using Interval = bn::interval<
double,
bi::policies<
bi::save_state<bi::rounded_transc_std<double> >,
bi::checking_base<double>
>
>;
#include <eigen3/Eigen/Dense>
using Matrix = Eigen::Matrix<Interval, 2, 2>;
using Vector = Eigen::Matrix<Interval, 2, 1>;
#include <iostream>
int main() {
Matrix m;
m <<
Interval {0.0, 1.0},
Interval {0.0, 0.0},
Interval {0.0, 0.0},
Interval {0.0, 1.0};
Vector v;
v <<
Interval {0.0, 1.0},
Interval {1.0, 2.0};
Vector prod = (m*v).eval();
std::cout << prod(0,0) << std::endl;
std::cout << prod(1,0) << std::endl;
}
打印:
[0,1]
[0,2]
当然你可以使用 Dynamic
extents。
我正在尝试使用区间算法为 R^n->R^m 函数编写 "divide and conquer" 根估计算法。我以前在 python 做过这个,但是性能太慢所以我决定试试 C++,我是一个初学者。
我搜索了一段时间,找到了 Boosts interval library,它似乎可以方便地解决我的问题。但是,我需要用这种间隔的矩阵进行计算。因为稍后我需要使用区间中点矩阵并(伪)反转它们,所以我认为 Eigen
可能是表示我的矩阵的好方法。
我的问题:这种方法真的是个好主意,尤其是在性能方面?如果是这样,我将如何继续使这样的矩阵能够包含间隔作为条目并使用基本操作(矩阵乘法等)
我希望能够做的事的一个例子:
#include <eigen3/Eigen/Dense>
#include <boost/numeric/interval.hpp>
using Eigen::MatrixXd;
using Eigen::VectorXd;
int main()
{
MatrixXd m(2,2);
VectorXd v(2);
Interval i1(0.0, 1.0);
Interval i2(1.0, 2.0);
Interval i3(0.0, 0.0);
m(0,0) = i1;
m(1,0) = i3;
m(0,1) = i3;
m(1,1) = i1;
v(0) = i1;
v(1) = i2;
std::cout << m*v << std::endl;
}
我对区间类型做的规范是
typedef boost::numeric::interval<double, boost::numeric::interval_lib::policies
<boost::numeric::interval_lib::save_state
<boost::numeric::interval_lib::rounded_transc_std<double> >,
boost::numeric::interval_lib::checking_base<double> > > Interval;
这最终应该输出类似 (0.0,1.0), (0.0,2.0) 的内容。现在这会引发错误 "Assigning scalar to incomparible type Interval",我不知道如何解决它,因为 Eigens 矩阵类型自然不支持间隔作为条目。
assigning to 'Scalar' (aka 'double') from incompatible type 'Interval' (aka 'interval < double, boost::numeric::interval_lib::policies < boost::numeric::interval_lib::save_state < boost::numeric::interval_lib::rounded_transc_std < double > >, boost::numeric::interval_lib::checking_base<double> > >')
欢迎任何(新手级!)参考和建议。
Docs say 那
typedef Matrix<double, Dynamic, Dynamic> MatrixXd;
这里有一些修复:
#include <boost/numeric/interval.hpp>
#include <boost/numeric/interval/utility.hpp>
#include <boost/numeric/interval/io.hpp>
namespace bn = boost::numeric;
namespace bi = bn::interval_lib;
using Interval = bn::interval<
double,
bi::policies<
bi::save_state<bi::rounded_transc_std<double> >,
bi::checking_base<double>
>
>;
#include <eigen3/Eigen/Dense>
using Matrix = Eigen::Matrix<Interval, 2, 2>;
using Vector = Eigen::Matrix<Interval, 2, 1>;
#include <iostream>
int main() {
Matrix m;
m <<
Interval {0.0, 1.0},
Interval {0.0, 0.0},
Interval {0.0, 0.0},
Interval {0.0, 1.0};
Vector v;
v <<
Interval {0.0, 1.0},
Interval {1.0, 2.0};
Vector prod = (m*v).eval();
std::cout << prod(0,0) << std::endl;
std::cout << prod(1,0) << std::endl;
}
打印:
[0,1]
[0,2]
当然你可以使用 Dynamic
extents。