间隔算法库:C ++中的boost :: numeric :: interval

问题描述 投票:1回答:1

我在一般情况下搜索了Stack Exchange和网络,包括增强说明页面,但是我仍然遇到一些问题,所以我希望有更多知识的人可以帮助我。

我需要计算理想的double或float类型的闭合,打开和半打开间隔的并集和交点。在搜索中,我找到了标题中提到的Boost库。

它们的船体功能不是真正的联合(在说明页上注明),但是也没有明确的替代,船体还不足以替代联合。加上它只能以固定的间隔工作,这使它成为一个相当低于标准的选择,但我找不到其他东西。 (如果您知道可以满足我需要的任何图书馆,请告诉我:)

就这个库而言,我遇到了一些我似乎无法自行解决或无法在网上找到任何解释的问题。

默认情况下,如果函数返回空间隔,则抛出异常并中止,例如,使用其交集函数进行两个无交集的间隔(如下面的代码所示),似乎有一种配置策略类的方法返回一个替换值,基本上可以使用NaN和空间隔正常工作,但是由于我对这样的外部库的了解有限,我到目前为止无法完成此工作。

下面,我列出了一些当前停留在的简单代码示例,因为我无法弄清楚如何使用或更改策略类以在空的间隔内工作。

我上下阅读说明,检查程序和策略页面,但我的知识似乎不足以完成这项工作。因此,我感谢您可以提供的任何帮助。

typedef boost::numeric::interval<double> I;
double inf = numeric_limits<double>::infinity();

I a(2,5);
cout << "a[" << boost::numeric::lower(a) << ", " << boost::numeric::upper(a) << "]\n";
I b(3,9);
cout << "b[" << boost::numeric::lower(b) << ", " << boost::numeric::upper(b) << "]\n";
I c(6,7);
cout << "b[" << boost::numeric::lower(c) << ", " << boost::numeric::upper(c) << "]\n";

cout << "Union a | b: " << "[" << boost::numeric::lower(boost::numeric::intersect(a, b)) << ", " << boost::numeric::upper(boost::numeric::intersect(a, b)) << "]\n";
// correctly lists [3,6] as intersection
cout << "Union a | c: " << "[" << boost::numeric::lower(boost::numeric::intersect(a, c)) << ", " << boost::numeric::upper(boost::numeric::intersect(a, c)) << "]\n";
// throws error due to empty interval being returned and not having lower or upper
c++ math boost intervals
1个回答
0
投票

听起来像您之后的库可能不适合数值计算。 Boost还具有ICL(间隔容器库)。

它具有间隔集/贴图,它们以离散或连续,有界或无界间隔工作。

它具有多种组合行为(连接相邻间隔,边界上的分隔间隔等,包括自定义组合器)。>>

[在映射时,它对共域具有多种收集/聚合策略(例如,当映射值是数字时为量词,或者在设置映射值时为收集器)。

这是一个简单的入门。 (请注意,我没有复制您的确切输入来显示各种打开/关闭和默认间隔类型)。

还请注意,相比之下,输出序列化似乎比较容易。

这只是在表面上放牧所以

#include <boost/icl/interval.hpp>
#include <boost/icl/interval_set.hpp>
#include <iostream>
namespace icl = boost::icl;

using S = icl::interval_set<double>;
using I = S::interval_type;
constexpr inline auto inf = std::numeric_limits<I::domain_type>::infinity();

int main() {
    I const
        a = I::closed(2,5),
        b(3,9),
        c = I::left_open(6,7);

#define INSPECT(expr) std::cout << #expr << ": " << (expr) << "\n";
    INSPECT(a);
    INSPECT(b);
    INSPECT(c);

    INSPECT(hull(a,b));
    INSPECT(S{a} | b);
    INSPECT(S{a} & b);
    INSPECT(S{a} & c);

    INSPECT(S{a} | b | c);
    // more efficient:
    INSPECT([=] { S s{a}; s.insert(b); s.insert(c); return s;}());

    INSPECT(S{a} - (S{b} | c));
    INSPECT(S{a} & (S{b} | c));
}

打印

a: [2,5]
b: [3,9)
c: (6,7]
hull(a,b): [2,9)
S{a} | b: {[2,9)}
S{a} & b: {[3,5]}
S{a} & c: {}
S{a} | b | c: {[2,9)}
[=] { S s{a}; s.insert(b); s.insert(c); return s;}(): {[2,9)}
S{a} - (S{b} | c): {[2,3)}
S{a} & (S{b} | c): {[3,5]}
© www.soinside.com 2019 - 2024. All rights reserved.