增压间隔矩阵

时间:2018-01-24 15:59:09

标签: c++ matrix boost intervals

我正在尝试使用区间算法为R ^ n-> R ^ m函数编写“分而治之”的根估计算法。我之前在python中做过这个,但性能太慢所以我决定给C ++一个去,我是一个初学者。

我搜索了一会儿找到Boosts间隔库,这似乎很方便处理我的问题。但是,我需要使用这种间隔的矩阵进行计算。因为我需要稍后使用区间中点的矩阵并(伪)反转它们,我认为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)的东西。现在这引发了错误“将标量分配给不可比类型间隔”,我不知道如何解决它,因为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> > >')

欢迎任何(noob-level!)参考和建议。

1 个答案:

答案 0 :(得分:1)

Docs say

TreeMap

这里有一些修正:

<强> Live On Coliru

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] 范围。