2

Javascript で保守的な区間演算を行うための優れた既存のライブラリはありますか?

保守的に言えば、実数の範囲を表す 2 つの間隔 (端点がたまたま浮動小数点) が与えられた場合、それらの間隔の合計には、元の間隔からの実数のすべての合計が含まれ、他の操作についても同様です。クイック検索で見つかった唯一のライブラリはhttps://github.com/Jeff-Tian/JavaScriptIntervalArithmeticですが、保守的ではないようです。

丸めモードにアクセスできないため、間隔が最適でない場合でも問題ありません (実際には速度の点で好ましい)。たとえば、[(1-epsilon)*(x*x),(1+epsilon)*(x*x)]これが最適な浮動小数点間隔よりも大きい場合でも、数値の 2 乗が保守的に で近似された場合は問題ありません。

4

2 に答える 2

3

https://github.com/maurizzzio/interval-arithmeticを見てください。その間隔は、表すことができる次/前の倍精度浮動小数点数で境界を定める浮動小数点数を表します

var Interval = require('interval-arithmetic');

// { lo: 0.3333333333333333, hi: 0.3333333333333333 }
new Interval().singleton(1 / 3); 

// { lo: 0.33333333333333326, hi: 0.33333333333333337 }
new Interval().boundedSingleton(1 / 3);

型付き配列は、倍精度浮動小数点数を構成するバイトを処理する方法を提供するようになりました。ライブラリは、ここでこの表現の有効桁数の最後のビットを変更し、すべての操作でこの丸め誤差が引き継がれます。

于 2015-05-12T18:36:58.487 に答える
0

「保守的」とはどういう意味かよくわかりませんが、カスタムオブジェクトを作成するよりもArrayのプロトタイプに追加する方が高速で、必要なメソッドを実装するだけでよいと思います。

Array.prototype._interval_plus = function (arr2) {
    return [this[0] + arr2[0], this[1] + arr2[1]];
};
Array.prototype._interval_minus = function (arr2) {
    return [this[0] - arr2[0], this[1] - arr2[1]];
};
Array.prototype._interval_multiply = function (arr2) {
    var ac = this[0] * arr2[0],
        ad = this[0] * arr2[1],
        bc = this[1] * arr2[0],
        bd = this[1] * arr2[1];
    return [Math.min(ac, ad, bc, bd), Math.max(ac, ad, bc, bd)];
};
Array.prototype._interval_divide = function (arr2) {
    var ac, ad, bc, bd;
    if (arr2[0] === 0 || arr2[1] === 0)
        throw new Error('division by zero');
    ac = this[0] / arr2[0],
    ad = this[0] / arr2[1],
    bc = this[1] / arr2[0],
    bd = this[1] / arr2[1];
    return [Math.min(ac, ad, bc, bd), Math.max(ac, ad, bc, bd)];
};
Array.prototype._interval_pow = function (arr2, pow) {
    var ac = this[0] * Math.pow(arr2[0], pow),
        ad = this[0] * Math.pow(arr2[1], pow),
        bc = this[1] * Math.pow(arr2[0], pow),
        bd = this[1] * Math.pow(arr2[1], pow);
    return [Math.min(ac, ad, bc, bd), Math.max(ac, ad, bc, bd)];
};

今、あなたは次のようなことができます

var x = [ 0  ,  1  ];
    y = [ 0.5,  3.5];
x._interval_plus(y)     // [ 0.5 ,   4.5 ]
 ._interval_multiply(y) // [ 0.25,  15.75]
 ._interval_minus(y)    // [-0.25,  12.25]
 ._interval_pow(y, 2);  // [-3.0625, 150.0625]
于 2014-04-15T02:36:51.227 に答える