Module: P1788

Defined in:
ext/p1788/p1788.cc,
lib/p1788/version.rb,
ext/p1788/p1788.cc,
ext/p1788/figure_wrapper.cc

Overview

Top-level namespace.

The P1788 module defines forward and reverse functions to work on intervals.

Set operations

P1788.intersection P1788.convex_hull

Forward-mode and reverse-mode elementary functions

Basic operations

P1788.neg P1788.add P1788.sub P1788.mul P1788.div P1788.recip P1788.sqr P1788.sqrt P1788.fma

Power functions

P1788.pown P1788.pow P1788.exp P1788.exp2 P1788.exp10 P1788.log P1788.log2 P1788.log10

Trigonometric functions

P1788.sin P1788.cos P1788.tan P1788.asin P1788.acos P1788.atan P1788.atan2

Hyperbolic functions

P1788.sinh P1788.cosh P1788.tanh P1788.asinh P1788.acosh P1788.atanh

Integer functions

P1788.sign P1788.ceil P1788.floor P1788.floorceil P1788.trunc P1788.round_ties_to_even P1788.round_ties_to_away

Absmax functions

P1788.abs P1788.min P1788.max

Reverse-mode elementary functions

Reverse basic operations

P1788.neg_rev P1788.add_rev P1788.sub_rev P1788.mul_rev P1788.mul_rev_to_pair P1788.div_rev P1788.recip_rev P1788.sqr_rev P1788.sqrt_rev

Reverse power functions

P1788.pown_rev P1788.pow_rev1 P1788.pow_rev2 P1788.exp_rev P1788.exp2_rev P1788.exp10_rev P1788.log_rev P1788.log2_rev P1788.log10_rev

Reverse trigonometric functions

P1788.sin_rev P1788.cos_rev P1788.tan_rev P1788.asin_rev P1788.acos_rev P1788.atan_rev

Reverse yperbolic functions

P1788.sinh_rev P1788.cosh_rev P1788.tanh_rev P1788.asinh_rev P1788.acosh_rev P1788.atanh_rev

Reverse abs function

P1788.abs_rev

Two-output division

P1788.div_to_pair

Cancellative addition and subtraction

P1788.cancel_plus P1788.cancel_minus

Defined Under Namespace

Classes: Figure, Interval, IntervalVector

Constant Summary collapse

VERSION =

Version of the P1788 gem

'1.0.0'
LIBIEEEP1788_VERSION =

Version of libieeep1788

Returns:

  • (String)
libieeep1788_version

Class Method Summary collapse

Class Method Details

.abs(x) ⇒ Interval

Absolute value of x

abs([𝒙])  =  hull{ |𝑥| │ 𝑥 ∈ [𝒙] }  ⊆  ℝ₊

Reverse function: abs_rev



3230
3231
3232
3233
# File 'ext/p1788/p1788.cc', line 3230

static VALUE p1788_abs(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, abs);
}

.abs_rev(c, x = ALL_REALS) ⇒ Interval

Reverse absolute value.

abs_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] │ |𝑥| ∈ [𝒄] }  ⊆  ℝ

Reverse function: abs



3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
# File 'ext/p1788/p1788.cc', line 3737

static VALUE p1788_abs_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE x, c, r;
	rb_scan_args(argc, argv, "11", &c, &x);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::abs_rev(p1788_rbobj2interval(c)));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::abs_rev(p1788_rbobj2interval(c), p1788_rbobj2interval(x)));
	}
	return r;
}

.acos(x) ⇒ Interval

Arc cosine of x, in radians.

acos([𝒙])  =  hull{ acos(𝑥) | 𝑥 ∈ [𝒙]∩[-1, 1] }  ⊆  [0, 𝛑]

Reverse function: acos_rev



2900
2901
2902
2903
# File 'ext/p1788/p1788.cc', line 2900

static VALUE p1788_acos(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, acos);
}

.acos_rev(c, x = ALL_REALS) ⇒ Interval

Reverse arc cosine

acos_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | acos(𝑥) ∈ [𝒄] }  =  { cos(𝑐) | 𝑐 ∈ [𝒄]∩[0, 𝛑] } ∩ [𝒙]  ⊆  [-1, 1]

Reverse function: cos



2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
# File 'ext/p1788/p1788.cc', line 2913

static VALUE p1788_acos_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::cos(Interval::intersection(p1788_rbobj2interval(rbc), zero_pi_set));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.acosh(x) ⇒ Interval

Inverse hyperbolic cosine of x.

acosh([𝒙])  =  hull{ acosh(𝑥) | 𝑥 ∈ [𝒙]∩[1,+∞] }  ⊆  ℝ₊

Reverse function: acosh_rev



3081
3082
3083
3084
# File 'ext/p1788/p1788.cc', line 3081

static VALUE p1788_acosh(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, acosh);
}

.tanh_rev(c, x = ALL_REALS) ⇒ Interval

Reverse inverse hyperbolic cosine

acosh_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | acosh(𝑥) ∈ [𝒄] }  =  { cosh(𝑐) | 𝑐 ∈ [𝒄] ∩ ℝ₊ } ∩ [𝒙]  ⊆  [1, +∞]

Reverse function: acosh



3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
# File 'ext/p1788/p1788.cc', line 3094

static VALUE p1788_acosh_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::cosh(Interval::intersection(p1788_rbobj2interval(rbc), pos_reals_set));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.add(x, y) ⇒ Interval

Arithmetic addition

add([𝒙], [𝒚])  =  hull{ 𝑥 + 𝑦 | 𝑥 ∈ [𝒙], 𝑦 ∈ [𝒚] }  ⊆  ℝ

Reverse function: add_rev



3321
3322
3323
3324
# File 'ext/p1788/p1788.cc', line 3321

static VALUE p1788_add(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, add);
}

.add_rev(b, c, x = ALL_REALS) ⇒ Interval

Reverse addition

add_rev([𝒃], [𝒄], [𝒙])  =  { 𝑥 ∈ [𝒙] | ∃ 𝑏 ∈ [𝒃] : 𝑥 + 𝑏 ∈ [𝒄] }  =  { 𝑐 - 𝑏 | 𝑏 ∈ [𝒃], 𝑐 ∈ [𝒄] } ∩ [𝒙]

Reverse function add



3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
# File 'ext/p1788/p1788.cc', line 3334

static VALUE p1788_add_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbb, rbc, rbx, rbr;
	rb_scan_args(argc, argv, "21", &rbb, &rbc, &rbx);
	Interval r = Interval::sub(p1788_rbobj2interval(rbc), p1788_rbobj2interval(rbb));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.asin(x) ⇒ Interval

Arc sine of x, in radians.

asin([𝒙])  =  hull{ asin(𝑥) | 𝑥 ∈ [𝒙]∩[-1, 1] }  ⊆  [-𝛑/2, 𝛑/2]

Reverse function: asin_rev



2869
2870
2871
2872
# File 'ext/p1788/p1788.cc', line 2869

static VALUE p1788_asin(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, asin);
}

.asin_rev(c, x = ALL_REALS) ⇒ Interval

Reverse arc sine

asin_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | asin(𝑥) ∈ [𝒄] }  =  { sin(𝑐) | 𝑐 ∈ [𝒄]∩[-𝛑/2, 𝛑/2] } ∩ [𝒙]  ⊆  [-1, 1]

Reverse function: asin



2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
# File 'ext/p1788/p1788.cc', line 2882

static VALUE p1788_asin_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::sin(Interval::intersection(p1788_rbobj2interval(rbc), minus_hpi_hpi_set));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.asinh(x) ⇒ Interval

Inverse hyperbolic sine of x.

asinh([𝒙])  =  hull{ asinh(𝑥) | 𝑥 ∈ [𝒙] }  ⊆  ℝ

Reverse function: asinh_rev



3050
3051
3052
3053
# File 'ext/p1788/p1788.cc', line 3050

static VALUE p1788_asinh(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, asinh);
}

.tanh_rev(c, x = ALL_REALS) ⇒ Interval

Reverse inverse hyperbolic sine

asinh_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | asinh(𝑥) ∈ [𝒄] }  =  { sinh(𝑐) | 𝑐 ∈ [𝒄] } ∩ [𝒙]  ⊆  ℝ

Reverse function: asinh



3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
# File 'ext/p1788/p1788.cc', line 3063

static VALUE p1788_asinh_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::sinh(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.atan(x) ⇒ Interval

Arc tangent of x.

atan([𝒙])  =  hull{ atan(𝑥) | 𝑥 ∈ [𝒙] }  ⊆  [-𝛑/2, 𝛑/2] 

Reverse function: atan_rev



2931
2932
2933
2934
# File 'ext/p1788/p1788.cc', line 2931

static VALUE p1788_atan(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, atan);
}

.atan2(y, x) ⇒ Interval

Principal value of the arc tangent of y/x

atan2([𝒚], [𝒙])  =  hull{ atan2(𝑦, 𝑥) | 𝑥 ∈ [𝒙], 𝑦 ∈ [𝒚] }  ⊆  [-𝛑, 𝛑] 

Reverse function: atan2_rev (not implemented yet)



2962
2963
2964
2965
2966
2967
# File 'ext/p1788/p1788.cc', line 2962

static VALUE p1788_atan2(VALUE self, VALUE y, VALUE x)
{
	VALUE r;
	P1788_NEW_RB_INTERVAL(r, Interval::atan2(p1788_interval_rb2ref(y), p1788_interval_rb2ref(x)));
	return r;
}

.atan_rev(c, x = ALL_REALS) ⇒ Interval

Reverse arc tangent

atan_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | atan(𝑥) ∈ [𝒄] }  =  { tan(𝑐) | 𝑐 ∈ [𝒄]∩[-𝛑/2, 𝛑/2] } ∩ [𝒙]  ⊆  ℝ

Reverse function: tan



2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
# File 'ext/p1788/p1788.cc', line 2944

static VALUE p1788_atan_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::tan(Interval::intersection(p1788_rbobj2interval(rbc), minus_hpi_hpi_set));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.atanh(x) ⇒ Interval

Inverse hyperbolic tangent of x.

atanh([𝒙])  =  hull{ atanh(𝑥) | 𝑥 ∈ [𝒙]∩[-1,1] }  ⊆  ℝ

Reverse function: atanh_rev



3112
3113
3114
3115
# File 'ext/p1788/p1788.cc', line 3112

static VALUE p1788_atanh(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, atanh);
}

.tanh_rev(c, x = ALL_REALS) ⇒ Interval

Reverse inverse hyperbolic tangent

atanh_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | atanh(𝑥) ∈ [𝒄] }  =  { tanh(𝑐) | 𝑐 ∈ [𝒄] } ∩ [𝒙]  ⊆  [-1, -1]

Reverse function: atanh



3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
# File 'ext/p1788/p1788.cc', line 3125

static VALUE p1788_atanh_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::tanh(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.cancel_minus(x, y) ⇒ Interval

Cancellative subtraction

Cancellative subtraction solves the following problem: Recover interval [𝒛] from intervals [𝒙] and [𝒚], given that [𝒙] = [𝒚] + [𝒛].

For any two bounded intervals [𝒙] and [𝒚], cancel_minus([𝒙], [𝒚]) is the tightest interval [𝒛] such that [𝒚] + [𝒛] ⊇ [𝒙].



3505
3506
3507
3508
# File 'ext/p1788/p1788.cc', line 3505

static VALUE p1788_cancel_minus(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, cancel_minus);
}

.cancel_plus(x, y) ⇒ Interval

Cancellative addition

cancel_plux([𝒙], [𝒚]) = cancel_minus([𝒙], -[𝒚])

See Also:



3516
3517
3518
3519
# File 'ext/p1788/p1788.cc', line 3516

static VALUE p1788_cancel_plus(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, cancel_plus);
}

.ceil(x) ⇒ Interval

Round x towards +∞

ceil([𝒙])  =  [ceil(𝒙), ceil(𝒙)]



3151
3152
3153
3154
# File 'ext/p1788/p1788.cc', line 3151

static VALUE p1788_ceil(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, ceil);
}

.convex_hull(x, y) ⇒ Interval

Interval hull of the union of x and y

convex_hull([𝒙], [𝒚])  =  hull( [𝒙] ∪ [𝒚] )



3493
3494
3495
3496
# File 'ext/p1788/p1788.cc', line 3493

static VALUE p1788_convex_hull(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, convex_hull);
}

.cos(x) ⇒ Interval

Cosine of x in radians.

cos([𝒙])  =  hull{ cos(𝑥) | 𝑥 ∈ [𝒙] }  ⊆  [-1, 1]

Reverse function: cos_rev



2845
2846
2847
2848
# File 'ext/p1788/p1788.cc', line 2845

static VALUE p1788_cos(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, cos);
}

.cos_rev(c, x = ALL_REALS) ⇒ Interval

Reverse cosine

cos_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | cos(𝑥) ∈ [𝒄] }  ⊆  ℝ

Reverse function: cos



3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
# File 'ext/p1788/p1788.cc', line 3856

static VALUE p1788_cos_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE x, c, r;
	rb_scan_args(argc, argv, "11", &c, &x);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::cos_rev(p1788_rbobj2interval(c)));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::cos_rev(p1788_rbobj2interval(c), p1788_rbobj2interval(x)));
	}
	return r;
}

.cosh(x) ⇒ Interval

Hyperbolic cosine of x.

cosh([𝒙])  =  hull{ (𝑒𝑥 + 𝑒-𝑥) / 2 | 𝑥 ∈ [𝒙] }  ⊆  [1, +∞]

Reverse function: cosh_rev



3007
3008
3009
3010
# File 'ext/p1788/p1788.cc', line 3007

static VALUE p1788_cosh(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, cosh);
}

.cosh_rev(c, x = ALL_REALS) ⇒ Interval

Reverse hyperbolic cosine

cosh_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | cosh(𝑥) ∈ [𝒄] }  ⊆  ℝ

Reverse function: cosh



3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
# File 'ext/p1788/p1788.cc', line 3898

static VALUE p1788_cosh_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE x, c, r;
	rb_scan_args(argc, argv, "11", &c, &x);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::cosh_rev(p1788_rbobj2interval(c)));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::cosh_rev(p1788_rbobj2interval(c), p1788_rbobj2interval(x)));
	}
	return r;
}

.div(x, y) ⇒ Interval

Arithmetic division

div([𝒙], [𝒚])  =  hull{ 𝑥/𝑦 | 𝑥 ∈ [𝒙], 𝑦 ∈ [𝒚] }  ⊆  ℝ

Reverse function: div_rev



3395
3396
3397
3398
# File 'ext/p1788/p1788.cc', line 3395

static VALUE p1788_div(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, div);
}

.div_rev(b, c, x = ALL_REALS) ⇒ Interval

Reverse division

div_rev([𝒃], [𝒄], [𝒙])  =  { 𝑥 ∈ [𝒙] | ∃ 𝑏 ∈ [𝒃] : 𝑥/𝑏 ∈ [𝒄] }  =  { 𝑐⋅𝑏 | 𝑏 ∈ [𝒃], 𝑐 ∈ [𝒄] } ∩ [𝒙]

Reverse function div



3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
# File 'ext/p1788/p1788.cc', line 3408

static VALUE p1788_div_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbb, rbc, rbx, rbr;
	rb_scan_args(argc, argv, "21", &rbb, &rbc, &rbx);
	Interval r = Interval::mul(p1788_rbobj2interval(rbc), p1788_rbobj2interval(rbb));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.div_to_pair(x, y) ⇒ Array<Interval>

Two-output division

Returns a pair of intervals, 𝒙 / (𝒚 ∩ ℝ₋) and 𝒙 / (𝒚 ∩ ℝ₊)

Parameters:

Returns:

  • (Array<Interval>)

    [∅, ∅] if 𝒙/𝒚 is empty, [[𝒙/𝒚], ∅] if 𝒙/𝒚 has one component, [[𝒙/𝒚]₁, [𝒙/𝒚]₂] if 𝒙/𝒚 has two components



3427
3428
3429
3430
3431
3432
3433
3434
# File 'ext/p1788/p1788.cc', line 3427

static VALUE p1788_div_to_pair(VALUE self, VALUE x, VALUE y)
{
	VALUE r1, r2;
	std::pair< Interval, Interval > p = Interval::mul_rev_to_pair(p1788_rbobj2interval(y), p1788_rbobj2interval(x));
	P1788_NEW_RB_INTERVAL(r1, p.first);
	P1788_NEW_RB_INTERVAL(r2, p.second);
	return rb_ary_new_from_args(2, r1, r2);
}

.exp(x) ⇒ Interval

e raised to the power of x

exp([𝒙])  =  hull{ 𝑒𝑥 | 𝑥 ∈ [𝒙] }  ⊆  ℝ₊

Reverse function: exp_rev



2647
2648
2649
2650
# File 'ext/p1788/p1788.cc', line 2647

static VALUE p1788_exp(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, exp);
}

.exp10(x) ⇒ Interval

10 raised to the power of x

exp10([𝒙])  =  hull{ 10𝑥 | 𝑥 ∈ [𝒙] }  ⊆  ℝ₊

Reverse function: exp10_rev



2709
2710
2711
2712
# File 'ext/p1788/p1788.cc', line 2709

static VALUE p1788_exp10(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, exp10);
}

.exp2_rev(c, x = ALL_REALS) ⇒ Interval

Reverse base 10 exponential

exp10_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | 10𝑥 ∈ [𝒄] }  =  { log10(𝑐) | 𝑐 ∈ [𝒄]∩ℝ₊ } ∩ [𝒙]  ⊆  ℝ

Reverse function: exp10



2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
# File 'ext/p1788/p1788.cc', line 2722

static VALUE p1788_exp10_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::log10(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.exp2(x) ⇒ Interval

2 raised to the power of x

exp2([𝒙])  =  hull{ 2𝑥 | 𝑥 ∈ [𝒙] }  ⊆  ℝ₊

Reverse function: exp2_rev



2678
2679
2680
2681
# File 'ext/p1788/p1788.cc', line 2678

static VALUE p1788_exp2(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, exp2);
}

.exp2_rev(c, x = ALL_REALS) ⇒ Interval

Reverse base 2 exponential

exp2_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | 2𝑥 ∈ [𝒄] }  =  { log2(𝑐) | 𝑐 ∈ [𝒄]∩ℝ₊ } ∩ [𝒙]  ⊆  ℝ

Reverse function: exp2



2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
# File 'ext/p1788/p1788.cc', line 2691

static VALUE p1788_exp2_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::log2(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.exp_rev(c, x = ALL_REALS) ⇒ Interval

Reverse exponential

exp_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | 𝑒𝑥 ∈ [𝒄] }  =  { log(𝑐) | 𝑐 ∈ [𝒄]∩ℝ₊ } ∩ [𝒙]  ⊆  ℝ

Reverse function: exp



2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
# File 'ext/p1788/p1788.cc', line 2660

static VALUE p1788_exp_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::log(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.floor(x) ⇒ Interval

Round x towards -∞

floor([𝒙])  =  [floor(𝒙), floor(𝒙)]



3161
3162
3163
3164
# File 'ext/p1788/p1788.cc', line 3161

static VALUE p1788_floor(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, floor);
}

.floorceil(x) ⇒ Interval

Inflate x towards nearest integer bounds

floorceil([𝒙])  =  [floor(𝒙), ceil(𝒙)]



3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
# File 'ext/p1788/p1788.cc', line 3171

static VALUE p1788_floorceil(VALUE self, VALUE x)
{
	VALUE r;
	if (is_an_interval_vector(x)) {
		const IntervalVector &v = p1788_vector_rb2ref(x);
		const size_t l = v.size();
		IntervalVector *t = new IntervalVector(l);
		for (size_t i = 0; i < l; i++)
			(*t)[i] = Interval(std::floor(Interval::inf(v[i])), std::ceil(Interval::sup(v[i])));
		r = p1788_vector_alloc_from_pointer(t);
	}
	else {
		Interval inter = p1788_rbobj2interval(x);
		P1788_NEW_RB_INTERVAL(r, Interval(std::floor(Interval::inf(inter)), std::ceil(Interval::sup(inter))));
	}
	return r;
}

.fma(x, y, z) ⇒ Interval

Fused multiply add

fma([𝒙], [𝒚], [𝒛])  =  hull{ 𝑥⋅𝑦 + 𝑧 | 𝑥 ∈ [𝒙], 𝑦 ∈ [𝒚], 𝑧 ∈ [𝒛] }  ⊆  ℝ



3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
# File 'ext/p1788/p1788.cc', line 3624

static VALUE p1788_fma(VALUE self, VALUE x, VALUE y, VALUE z)
{
	VALUE argv[3] = {x, y, z};
	int l = p1788_check_all_vectors_have_the_same_length(3, argv);
	VALUE r;
	if (l < 0) {
		P1788_NEW_RB_INTERVAL(
				r,
				Interval::fma(
					p1788_rbobj2interval(x),
					p1788_rbobj2interval(y),
					p1788_rbobj2interval(z)
					)
				);
	}
	else {
		IntervalVector vx;
		IntervalVector vy;
		IntervalVector vz;
		IntervalVector *vxp;
		IntervalVector *vyp;
		IntervalVector *vzp;
		if (is_an_interval_vector(x))
			vxp = &p1788_vector_rb2ref(x);
		else {
			vx = std::move(IntervalVector(l, p1788_rbobj2interval(x)));
			vxp = &vx;
		}
		if (is_an_interval_vector(y))
			vyp = &p1788_vector_rb2ref(y);
		else {
			vy = std::move(IntervalVector(l, p1788_rbobj2interval(y)));
			vyp = &vy;
		}
		if (is_an_interval_vector(z))
			vzp = &p1788_vector_rb2ref(z);
		else {
			vz = std::move(IntervalVector(l, p1788_rbobj2interval(z)));
			vzp = &vz;
		}
		IntervalVector *m = new IntervalVector(l);
		for (int i = 0; i < l; i++)
			(*m)[i] = Interval::fma((*vxp)[i], (*vyp)[i], (*vzp)[i]);
		r = p1788_vector_alloc_from_pointer(m);
	}
	return r;
}

.intersection(x, y) ⇒ Interval

Intersection

intersection([𝒙], [𝒚])  =  [𝒙] ∩ [𝒚]



3483
3484
3485
3486
# File 'ext/p1788/p1788.cc', line 3483

static VALUE p1788_intersection(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, intersection);
}

.log(x) ⇒ Interval

Natural logarithm of x.

log([𝒙])  =  hull{ ln(𝑥) | 𝑥 ∈ [𝒙]∩ℝ₊ }  ⊆  ℝ

Reverse function: log_rev



2740
2741
2742
2743
# File 'ext/p1788/p1788.cc', line 2740

static VALUE p1788_log(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, log);
}

.log10(x) ⇒ Interval

Base 10 logarithm of x

log10([𝒙])  =  hull{ ln(𝑥)/ln(10) | 𝑥 ∈ [𝒙]∩ℝ₊ }  ⊆  ℝ

Reverse function: log10_rev



2802
2803
2804
2805
# File 'ext/p1788/p1788.cc', line 2802

static VALUE p1788_log10(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, log10);
}

.log10_rev(c, x = ALL_REALS) ⇒ Interval

Reverse base 10 logarithm

log10_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | log10(𝑥) ∈ [𝒄] }  =  { 10𝑐 | 𝑐 ∈ [𝒄] } ∩ [𝒙]  ⊆  ℝ₊

Reverse function: log10



2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
# File 'ext/p1788/p1788.cc', line 2815

static VALUE p1788_log10_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::exp10(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.log2(x) ⇒ Interval

Base 2 logarithm of x

log2([𝒙])  =  hull{ ln(𝑥)/ln(2) | 𝑥 ∈ [𝒙]∩ℝ₊ }  ⊆  ℝ

Reverse function: log2_rev



2771
2772
2773
2774
# File 'ext/p1788/p1788.cc', line 2771

static VALUE p1788_log2(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, log2);
}

.log2_rev(c, x = ALL_REALS) ⇒ Interval

Reverse base 2 logarithm

log2_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | log2(𝑥) ∈ [𝒄] }  =  { 2𝑐 | 𝑐 ∈ [𝒄] } ∩ [𝒙]  ⊆  ℝ₊

Reverse function: log2



2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
# File 'ext/p1788/p1788.cc', line 2784

static VALUE p1788_log2_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::exp2(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.log_rev(c, x = ALL_REALS) ⇒ Interval

Reverse natural logarithm

log_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | log(𝑥) ∈ [𝒄] }  =  { 𝑒𝑐 | 𝑐 ∈ [𝒄] } ∩ [𝒙]  ⊆  ℝ₊

Reverse function: log



2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
# File 'ext/p1788/p1788.cc', line 2753

static VALUE p1788_log_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::exp(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.max(a, b, ...) ⇒ Interval

Maximum of two or more intervals

max([𝒂], [𝒃])  =  [max(𝒂, 𝒃), max(𝒂, 𝒃)]



3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
# File 'ext/p1788/p1788.cc', line 3584

static VALUE p1788_max(int argc, VALUE *argv, VALUE self)
{
	if (argc < 2)
		rb_raise(rb_eArgError, "expecting at leas 2 arguments, not %d", argc);
	int l = p1788_check_all_vectors_have_the_same_length(argc, argv);
	VALUE r;
	if (l < 0) {
		Interval m = Interval::max(p1788_rbobj2interval(argv[0]), p1788_rbobj2interval(argv[1]));
		for (int i = 2; i < argc; i++)
			m = Interval::max(m, p1788_rbobj2interval(argv[i]));
		P1788_NEW_RB_INTERVAL(r, m);
	}
	else {
		IntervalVector *m;
		if (is_an_interval_vector(argv[0]))
			m = new IntervalVector(p1788_vector_rb2ref(argv[0]));
		else
			m = new IntervalVector(l, p1788_rbobj2interval(argv[0]));
		for (int i = 1; i < argc; i++) {
			if (is_an_interval_vector(argv[i])) {
				IntervalVector &n = p1788_vector_rb2ref(argv[i]);
				for (int j = 0; j < l; j++)
					(*m)[j] = Interval::max((*m)[j], n[j]);
			}
			else {
				Interval n = p1788_rbobj2interval(argv[i]);
				for (int j = 0; j < l; j++)
					(*m)[j] = Interval::max((*m)[j], n);
			}
		}
		r = p1788_vector_alloc_from_pointer(m);
	}
	return r;
}

.min(a, b, ...) ⇒ Interval

Minimum of two or more intervals

min([𝒂], [𝒃])  =  [min(𝒂, 𝒃), min(𝒂, 𝒃)]



3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
# File 'ext/p1788/p1788.cc', line 3543

static VALUE p1788_min(int argc, VALUE *argv, VALUE self)
{
	if (argc < 2)
		rb_raise(rb_eArgError, "expecting at leas 2 arguments, not %d", argc);
	int l = p1788_check_all_vectors_have_the_same_length(argc, argv);
	VALUE r;
	if (l < 0) {
		Interval m = Interval::min(p1788_rbobj2interval(argv[0]), p1788_rbobj2interval(argv[1]));
		for (int i = 2; i < argc; i++)
			m = Interval::min(m, p1788_rbobj2interval(argv[i]));
		P1788_NEW_RB_INTERVAL(r, m);
	}
	else {
		IntervalVector *m;
		if (is_an_interval_vector(argv[0]))
			m = new IntervalVector(p1788_vector_rb2ref(argv[0]));
		else
			m = new IntervalVector(l, p1788_rbobj2interval(argv[0]));
		for (int i = 1; i < argc; i++) {
			if (is_an_interval_vector(argv[i])) {
				IntervalVector &n = p1788_vector_rb2ref(argv[i]);
				for (int j = 0; j < l; j++)
					(*m)[j] = Interval::min((*m)[j], n[j]);
			}
			else {
				Interval n = p1788_rbobj2interval(argv[i]);
				for (int j = 0; j < l; j++)
					(*m)[j] = Interval::min((*m)[j], n);
			}
		}
		r = p1788_vector_alloc_from_pointer(m);
	}
	return r;
}

.mul(x, y) ⇒ Interval

Arithmetic multiplication

mul([𝒙], [𝒚])  =  hull{ 𝑥⋅𝑦 | 𝑥 ∈ [𝒙], 𝑦 ∈ [𝒚] }  ⊆  ℝ

Reverse function: mul_rev



3383
3384
3385
3386
# File 'ext/p1788/p1788.cc', line 3383

static VALUE p1788_mul(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, mul);
}

.mul_rev(b, c, x = ALL_REALS) ⇒ Interval

Reverse multiplication

mul_rev([𝒃], [𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | ∃ 𝑏 ∈ [𝒃] : 𝑥⋅𝑏 ∈ [𝒄] }  ⊆  ℝ

Reverse function mul



3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
# File 'ext/p1788/p1788.cc', line 3695

static VALUE p1788_mul_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE b, c, x, r;
	rb_scan_args(argc, argv, "21", &b, &c, &x);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::mul_rev(p1788_rbobj2interval(b), p1788_rbobj2interval(c)));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::mul_rev(p1788_rbobj2interval(b), p1788_rbobj2interval(c), p1788_rbobj2interval(x)));
	}
	return r;
}

.mul_rev_to_pair(b, c) ⇒ Array<Interval>

Two-output division

[𝒄]/[𝒃] = { 𝑥 ∈ ℝ | ∃ 𝑏 ∈ [𝒃] : 𝑥⋅𝑏 ∈ [𝒄] }

Returns:

  • (Array<Interval>)

    a two elements array of intervals: [∅, ∅] if 𝒄/𝒃 is empty, [[𝒄/𝒃], ∅] if 𝒄/𝒃 has one component, [[𝒄/𝒃]₁, [𝒄/𝒃]₂] if 𝒄/𝒃 has two components



3678
3679
3680
3681
3682
3683
3684
3685
# File 'ext/p1788/p1788.cc', line 3678

static VALUE p1788_mul_rev_to_pair(VALUE self, VALUE b, VALUE c)
{
	VALUE r1, r2;
	std::pair< Interval, Interval > p = Interval::mul_rev_to_pair(p1788_rbobj2interval(b), p1788_rbobj2interval(c));
	P1788_NEW_RB_INTERVAL(r1, p.first);
	P1788_NEW_RB_INTERVAL(r2, p.second);
	return rb_ary_new_from_args(2, r1, r2);
}

.neg(x) ⇒ Interval

Arithmetic opposite

neg([𝒙])  =  { -𝑥 │ 𝑥 ∈ [𝒙] }  =  [-𝒙, -𝒙]

Reverse function: neg_rev



3251
3252
3253
3254
# File 'ext/p1788/p1788.cc', line 3251

static VALUE p1788_neg(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, neg);
}

.neg_rev(c, x = ALL_REALS) ⇒ Interval

Reverse opposite

neg_rev([𝒄], [𝒙])  =  { 𝑥 ∈ [𝒙] | -𝑥 ∈ [𝒄] }  =  { -𝑐 | 𝑐 ∈ [𝒄] } ∩ [𝒙]

Reverse function: neg



3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
# File 'ext/p1788/p1788.cc', line 3264

static VALUE p1788_neg_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::neg(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.pos(x) ⇒ Interval

+x

Returns:



3239
3240
3241
3242
# File 'ext/p1788/p1788.cc', line 3239

static VALUE p1788_pos(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, pos);
}

.pow(x, y) ⇒ Interval

Power function

pow([𝒙], [𝒚])  =  hull{ 𝑥𝑦 | (𝑥, 𝑦) ∈ {𝑥 ∈ [𝒙], 𝑦 ∈ [𝒚] | 𝑥>0} ∪ {𝑥=0, 𝑦 ∈ [𝒚] | 𝑦>0} }  ⊆  ℝ₊

Reverse functions: pow_rev1 and pow_rev2



3443
3444
3445
3446
# File 'ext/p1788/p1788.cc', line 3443

static VALUE p1788_pow(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, pow);
}

.pow_rev1(b, c, x = ALL_REALS) ⇒ Interval

Reverse power function (base)

pow_rev1([𝒃], [𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | ∃ 𝑏 ∈ [𝒃] : 𝑥𝑏 ∈ [𝒄] }  ⊆  ℝ₊

Reverse function: pow



3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
# File 'ext/p1788/p1788.cc', line 3786

static VALUE p1788_pow_rev1(int argc, VALUE *argv, VALUE self)
{
	VALUE rbb, rbc, rbx, rbr;
	rb_scan_args(argc, argv, "21", &rbb, &rbc, &rbx);
	Interval b = p1788_rbobj2interval(rbb);
	Interval c = p1788_rbobj2interval(rbc);
	Interval x = (rbx == Qnil) ? Interval(-INF, INF) : p1788_rbobj2interval(rbx);

	Interval lnx = Interval::log(x);
	Interval m   = Interval::intersection(Interval::log(c), Interval::mul(b, lnx));
	Interval l   = Interval::mul_rev(b, m, lnx);
	Interval r   = Interval::intersection(Interval::exp(l), x);

	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.pow_rev2(a, c, x = ALL_REALS) ⇒ Interval

Reverse power function (exponent)

pow_rev2([𝒂], [𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | ∃ 𝑎 ∈ [𝒂] : 𝑎𝑥 ∈ [𝒄] }  ⊆  ℝ

Reverse function: pow



3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
# File 'ext/p1788/p1788.cc', line 3811

static VALUE p1788_pow_rev2(int argc, VALUE *argv, VALUE self)
{
	VALUE rba, rbc, rbx, rbr;
	rb_scan_args(argc, argv, "21", &rba, &rbc, &rbx);
	Interval a = p1788_rbobj2interval(rba);
	Interval c = p1788_rbobj2interval(rbc);
	Interval x = (rbx == Qnil) ? Interval(-INF, INF) : p1788_rbobj2interval(rbx);

	Interval lna = Interval::log(a);
	Interval m   = Interval::intersection(Interval::log(c), Interval::mul(x, lna));
	Interval r   = Interval::mul_rev(lna, m, x);

	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.pown(b, n) ⇒ Interval

Power with integer exponent

pow([𝒃], n)  =  hull{ 𝑏ⁿ | 𝑏 ∈ [𝒃] }  ⊆  ℝ if n odd, ℝ₊ if n even, {1} if n = 0

Reverse function pown_rev

Parameters:

  • b (Interval)

    base

  • n (Integer)

    integer exponent



3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
# File 'ext/p1788/p1788.cc', line 3457

static VALUE p1788_pown(VALUE self, VALUE b, VALUE n)
{
	VALUE r;
	int p;
	if (!RB_INTEGER_TYPE_P(n))
		rb_raise(rb_eTypeError, "expecting an integer as exponent, not a %" PRIsVALUE, rb_class_name(rb_class_of(n)));
	p = NUM2INT(n);
	if (is_an_interval_vector(b)) {
		const IntervalVector &v = p1788_vector_rb2ref(b);
		const size_t l = v.size();
		IntervalVector *t = new IntervalVector(l);
		for (size_t i = 0; i < l; i++)
			(*t)[i] = Interval::pown(v[i], p);
		r = p1788_vector_alloc_from_pointer(t);
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::pown(p1788_rbobj2interval(b), p));
	}
	return r;
}

.pown_rev(n, c, x = ALL_REALS) ⇒ Interval

Reverse power with integer exponent

pown_rev(𝑛, [𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | 𝑥ⁿ ∈ [𝒄] }  ⊆  ℝ

Reverse function: pown

Parameters:

  • n (Integer)

    integer exponent

  • c (Interval)
  • x (Interval) (defaults to: ALL_REALS)


3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
# File 'ext/p1788/p1788.cc', line 3761

static VALUE p1788_pown_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE x, c, r, n;
	int p;
	rb_scan_args(argc, argv, "21", &n, &c, &x);
	if (!RB_INTEGER_TYPE_P(n))
		rb_raise(rb_eTypeError, "expecting an integer as exponent, not a %" PRIsVALUE, rb_class_name(rb_class_of(n)));
	p = NUM2INT(n);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::pown_rev(p1788_rbobj2interval(c), p));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::pown_rev(p1788_rbobj2interval(c), p1788_rbobj2interval(x), p));
	}
	return r;
}

.recip(x) ⇒ Interval

Reciprocal of x

recip([𝒙])  =  hull{ 1/𝑥 | 𝑥 ∈ [𝒙] }  ⊆  ℝ

Reverse function: recip_rev



2570
2571
2572
2573
# File 'ext/p1788/p1788.cc', line 2570

static VALUE p1788_recip(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, recip);
}

.recip_rev(c, x = ALL_REALS) ⇒ Interval

Reverse reciprocal

recip_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | 1/𝑥 ∈ [𝒄] }  ⊆  ℝ

Reverse function: recip



2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
# File 'ext/p1788/p1788.cc', line 2583

static VALUE p1788_recip_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE x, c, r;
	rb_scan_args(argc, argv, "11", &c, &x);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::mul_rev(p1788_rbobj2interval(c), Interval(1.0, 1.0)));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::mul_rev(p1788_rbobj2interval(c), Interval(1.0, 1.0), p1788_rbobj2interval(x)));
	}
	return r;
}

.round_ties_to_away(x) ⇒ Interval

Round x, ties to away from zero

Round bounds to their nearest integer values, rounding halfway cases away from zero.

round_ties_to_away([𝒙])  =  [round_ties_to_away(𝒙), round_ties_to_away(𝒙)]



3218
3219
3220
3221
# File 'ext/p1788/p1788.cc', line 3218

static VALUE p1788_round_ties_to_away(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, round_ties_to_away);
}

.round_ties_to_even(x) ⇒ Interval

Round x, ties to even

Round bounds to their nearest integer values, rounding halfway cases to nearest even.

round_ties_to_even([𝒙])  =  [round_ties_to_even(𝒙), round_ties_to_even(𝒙)]



3206
3207
3208
3209
# File 'ext/p1788/p1788.cc', line 3206

static VALUE p1788_round_ties_to_even(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, round_ties_to_even);
}

.sign(x) ⇒ Interval

Sign of x

sign([𝒙])  ⊆  [-1, 1]  ({-1} if 𝒙 < 0, {1} if 𝒙 > 0, {0} if [𝒙] = {0})



3141
3142
3143
3144
# File 'ext/p1788/p1788.cc', line 3141

static VALUE p1788_sign(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, sign);
}

.sin(x) ⇒ Interval

Sine of x in radians.

sin([𝒙])  =  hull{ sin(𝑥) | 𝑥 ∈ [𝒙] }  ⊆  [-1, 1]

Reverse function: sin_rev



2833
2834
2835
2836
# File 'ext/p1788/p1788.cc', line 2833

static VALUE p1788_sin(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, sin);
}

.sin_rev(c, x = ALL_REALS) ⇒ Interval

Reverse sine

sin_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | sin(𝑥) ∈ [𝒄] }  ⊆  ℝ

Reverse function: sin



3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
# File 'ext/p1788/p1788.cc', line 3835

static VALUE p1788_sin_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE x, c, r;
	rb_scan_args(argc, argv, "11", &c, &x);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::sin_rev(p1788_rbobj2interval(c)));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::sin_rev(p1788_rbobj2interval(c), p1788_rbobj2interval(x)));
	}
	return r;
}

.sinh(x) ⇒ Interval

Hyperbolic sine of x.

sinh([𝒙])  =  hull{ (𝑒𝑥 - 𝑒-𝑥) / 2 | 𝑥 ∈ [𝒙] }  ⊆  ℝ

Reverse function: sinh_rev



2976
2977
2978
2979
# File 'ext/p1788/p1788.cc', line 2976

static VALUE p1788_sinh(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, sinh);
}

.sinh_rev(c, x = ALL_REALS) ⇒ Interval

Reverse hyperbolic sine

sinh_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | sinh(𝑥) ∈ [𝒄] }  =  { asinh(𝑐) | 𝑐 ∈ [𝒄] } ∩ [𝒙]  ⊆  ℝ

Reverse function: sinh



2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
# File 'ext/p1788/p1788.cc', line 2989

static VALUE p1788_sinh_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::asinh(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.sqr(x) ⇒ Interval

Square of x

sqr([𝒙])  =  hull{ 𝑥² | 𝑥 ∈ [𝒙] }  ⊆  ℝ₊

Reverse function: sqr_rev



2603
2604
2605
2606
# File 'ext/p1788/p1788.cc', line 2603

static VALUE p1788_sqr(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, sqr);
}

.sqr_rev(c, x = ALL_REALS) ⇒ Interval

Reverse square

sqr_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | 𝑥² ∈ [𝒄] }  ⊆  ℝ

Reverse function: sqr



3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
# File 'ext/p1788/p1788.cc', line 3716

static VALUE p1788_sqr_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE x, c, r;
	rb_scan_args(argc, argv, "11", &c, &x);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::sqr_rev(p1788_rbobj2interval(c)));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::sqr_rev(p1788_rbobj2interval(c), p1788_rbobj2interval(x)));
	}
	return r;
}

.sqrt(x) ⇒ Interval

Square root of x

sqrt([𝒙])  =  hull{ 𝑥½ | 𝑥 ∈ [𝒙]∩ℝ₊ }  ⊆  ℝ₊

Reverse function: sqrt_rev



2615
2616
2617
2618
# File 'ext/p1788/p1788.cc', line 2615

static VALUE p1788_sqrt(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, sqrt);
}

.sqrt_rev(c, x = ALL_REALS) ⇒ Interval

Reverse square root

sqrt_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | 𝑥½ ∈ [𝒄] }  =  { 𝑐² | 𝑐 ∈ [𝒄]∩ℝ₊ } ∩ [𝒙]  ⊆  ℝ₊

Reverse function: sqrt



2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
# File 'ext/p1788/p1788.cc', line 2628

static VALUE p1788_sqrt_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  c = p1788_rbobj2interval(rbc);
	Interval  r = Interval::sqr(Interval::intersection(c, pos_reals_set));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.sub(x, y) ⇒ Interval

Arithmetic subtraction

sub([𝒙], [𝒚])  =  hull{ 𝑥 - 𝑦 | 𝑥 ∈ [𝒙], 𝑦 ∈ [𝒚] }  ⊆  ℝ

Reverse function: sub_rev



3352
3353
3354
3355
# File 'ext/p1788/p1788.cc', line 3352

static VALUE p1788_sub(VALUE self, VALUE x, VALUE y)
{
	P1788_MATH_BINARY_OP(x, y, sub);
}

.sub_rev(b, c, x = ALL_REALS) ⇒ Interval

Reverse subtraction

sub_rev([𝒃], [𝒄], [𝒙])  =  { 𝑥 ∈ [𝒙] | ∃ 𝑏 ∈ [𝒃] : 𝑥 - 𝑏 ∈ [𝒄] }  =  { 𝑐 + 𝑏 | 𝑏 ∈ [𝒃], 𝑐 ∈ [𝒄] } ∩ [𝒙]

Reverse function sub



3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
# File 'ext/p1788/p1788.cc', line 3365

static VALUE p1788_sub_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbb, rbc, rbx, rbr;
	rb_scan_args(argc, argv, "21", &rbb, &rbc, &rbx);
	Interval r = Interval::add(p1788_rbobj2interval(rbc), p1788_rbobj2interval(rbb));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.tan(x) ⇒ Interval

Tangent of x in radians.

tan([𝒙])  =  hull{ tan(𝑥) | 𝑥 ∈ [𝒙] }  ⊆  ℝ

Reverse function: tan_rev



2857
2858
2859
2860
# File 'ext/p1788/p1788.cc', line 2857

static VALUE p1788_tan(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, tan);
}

.tan_rev(c, x = ALL_REALS) ⇒ Interval

Reverse tangent

tan_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | tan(𝑥) ∈ [𝒄] }  ⊆  ℝ

Reverse function: tan



3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
# File 'ext/p1788/p1788.cc', line 3877

static VALUE p1788_tan_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE x, c, r;
	rb_scan_args(argc, argv, "11", &c, &x);
	if (x == Qnil) {
		P1788_NEW_RB_INTERVAL(r, Interval::tan_rev(p1788_rbobj2interval(c)));
	}
	else {
		P1788_NEW_RB_INTERVAL(r, Interval::tan_rev(p1788_rbobj2interval(c), p1788_rbobj2interval(x)));
	}
	return r;
}

.tanh(x) ⇒ Interval

Hyperbolic tangent of x.

tanh([𝒙])  =  hull{ sinh(𝑥) / cosh(𝑥) | 𝑥 ∈ [𝒙] }  ⊆  [-1, 1]

Reverse function: tanh_rev



3019
3020
3021
3022
# File 'ext/p1788/p1788.cc', line 3019

static VALUE p1788_tanh(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, tanh);
}

.tanh_rev(c, x = ALL_REALS) ⇒ Interval

Reverse hyperbolic tangent

tanh_rev([𝒄], [𝒙])  =  hull{ 𝑥 ∈ [𝒙] | tanh(𝑥) ∈ [𝒄] }  =  { atanh(𝑐) | 𝑐 ∈ [𝒄]∩[-1, 1] } ∩ [𝒙]  ⊆  ℝ

Reverse function: tanh



3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
# File 'ext/p1788/p1788.cc', line 3032

static VALUE p1788_tanh_rev(int argc, VALUE *argv, VALUE self)
{
	VALUE rbc, rbx, rbr;
	rb_scan_args(argc, argv, "11", &rbc, &rbx);
	Interval  r = Interval::atanh(p1788_rbobj2interval(rbc));
	if (rbx != Qnil)
		r = Interval::intersection(r, p1788_rbobj2interval(rbx));
	P1788_NEW_RB_INTERVAL(rbr, r);
	return rbr;
}

.trunc(x) ⇒ Interval

Round x towards 0

trunc([𝒙])  =  [trunc(𝒙), trunc(𝒙)]



3194
3195
3196
3197
# File 'ext/p1788/p1788.cc', line 3194

static VALUE p1788_trunc(VALUE self, VALUE x)
{
	P1788_MATH_UNARY_OP(x, trunc);
}