1#![deny(rustdoc::broken_intra_doc_links)]
2#![feature(error_generic_member_access)]
3
4pub mod errors;
14pub mod functions;
15pub mod neumaier_compensated_sum;
16
17use crate::{
18 errors::{
19 ComplexValueErrors, ComplexValueValidator, RealValueErrors, RealValueValidator,
20 TryFromf64Errors,
21 },
22 functions::{Abs, Reciprocal, Sqrt},
23};
24use num::{Complex, One, Zero};
25use num_traits::ops::mul_add::MulAddAssign;
26use serde::{de::DeserializeOwned, Serialize};
27use std::{
28 backtrace::Backtrace,
29 cmp::Ordering,
30 fmt::{self},
31 num::FpCategory,
32};
33use thiserror::Error;
34
35#[cfg(feature = "rug")]
37use derive_more::{
38 Add, AddAssign, AsRef, Display, Div, DivAssign, LowerExp, Mul, MulAssign, Neg, Sub, SubAssign,
39};
40
41#[cfg(not(feature = "rug"))]
43use std::{
44 fmt::LowerExp,
45 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
46};
47
48#[cfg(feature = "rug")]
50use duplicate::duplicate_item;
51
52#[cfg(feature = "rug")]
54use rug::ops::{CompleteRound, Pow as RugPow};
55
56#[cfg(feature = "rug")]
58use serde::Deserialize;
59
60pub trait IntoInner {
63 type Target;
65
66 fn into_inner(self) -> Self::Target;
68}
69#[derive(Debug, Error)]
73pub enum RecipErrors<ValueType: Sized> {
74 #[error("the input value is NaN!")]
76 NanInput { backtrace: Backtrace },
77
78 #[error("the output value is NaN!")]
80 NanOutput { backtrace: Backtrace },
81
82 #[error("the input value is zero!")]
84 DivisionByZero { backtrace: Backtrace },
85
86 #[error("the output value ({value:?}) is subnormal!")]
88 Underflow {
89 value: ValueType,
90 backtrace: Backtrace,
91 },
92
93 #[error("The output value cannot be represented becaus an overflow has occourred")]
95 Overflow { backtrace: Backtrace },
96}
97pub trait NegAssign {
103 fn neg_assign(&mut self);
105}
106
107#[duplicate::duplicate_item(
108 T;
109 [f64];
110 [Complex<f64>];
111)]
112impl NegAssign for T {
114 fn neg_assign(&mut self) {
116 *self = -*self;
117 }
118}
119
120#[cfg(feature = "rug")]
122#[duplicate::duplicate_item(
123 T;
124 [rug::Float];
125 [rug::Complex];
126)]
127impl NegAssign for T {
129 fn neg_assign(&mut self) {
131 <T as rug::ops::NegAssign>::neg_assign(self);
132 }
133}
134pub trait Pow<ExponentType> {
138 fn pow_(self, exponent: ExponentType) -> Self;
140}
141
142#[duplicate::duplicate_item(
143 T;
144 [f64];
145 [Complex<f64>];
146)]
147impl Pow<f64> for T {
148 fn pow_(self, exponent: f64) -> Self {
150 self.powf(exponent)
151 }
152}
153
154#[duplicate::duplicate_item(
155 T exponent_type func_name;
156 [f64] [i32] [powi];
157 [Complex<f64>] [i32] [powi];
158 [Complex<f64>] [u32] [powu];
159)]
160impl Pow<exponent_type> for T {
161 fn pow_(self, exponent: exponent_type) -> Self {
163 self.func_name(exponent)
164 }
165}
166
167#[duplicate::duplicate_item(
168 T exponent_type func_name;
169 [f64] [i8] [powi];
170 [f64] [u8] [powi];
171 [f64] [i16] [powi];
172 [f64] [u16] [powi];
173 [Complex<f64>] [i8] [powi];
174 [Complex<f64>] [u8] [powu];
175 [Complex<f64>] [i16] [powi];
176 [Complex<f64>] [u16] [powu];
177)]
178impl Pow<exponent_type> for T {
179 fn pow_(self, exponent: exponent_type) -> Self {
181 self.func_name(exponent.into())
182 }
183}
184
185#[duplicate::duplicate_item(
186 T exponent_type func_name;
187 [f64] [u32] [powi];
188 [f64] [i64] [powi];
189 [f64] [u64] [powi];
190 [f64] [i128] [powi];
191 [f64] [u128] [powi];
192 [f64] [usize] [powi];
193 [Complex<f64>] [i64] [powi];
194 [Complex<f64>] [i128] [powi];
195 [Complex<f64>] [u64] [powu];
196 [Complex<f64>] [u128] [powu];
197 [Complex<f64>] [usize] [powu];
198)]
199impl Pow<exponent_type> for T {
200 fn pow_(self, exponent: exponent_type) -> Self {
202 self.func_name(exponent.try_into().unwrap())
203 }
204}
205
206pub trait PowTrait<T: NumKernel>:
207 Pow<T::RealType>
208 + Pow<i8>
209 + Pow<u8>
210 + Pow<i16>
211 + Pow<u16>
212 + Pow<i32>
213 + Pow<u32>
214 + Pow<i64>
215 + Pow<u64>
216 + Pow<i128>
217 + Pow<u128>
218 + Pow<usize>
219{
220}
221
222impl PowTrait<Native64> for f64 {}
223impl PowTrait<Native64> for Complex<f64> {}
224pub trait Arithmetic: Sized
229where
230 Self: Add<Self, Output = Self>
231 + for<'a> Add<&'a Self, Output = Self>
232 + AddAssign
233 + for<'a> AddAssign<&'a Self>
234 + Sub<Output = Self>
235 + for<'a> Sub<&'a Self, Output = Self>
236 + SubAssign
237 + for<'a> SubAssign<&'a Self>
238 + Mul<Output = Self>
239 + for<'a> Mul<&'a Self, Output = Self>
240 + MulAssign
241 + for<'a> MulAssign<&'a Self>
242 + Div<Output = Self>
243 + for<'a> Div<&'a Self, Output = Self>
244 + DivAssign
245 + for<'a> DivAssign<&'a Self>
246 + Neg
247 + NegAssign
248 + LowerExp,
249{
250}
251
252pub trait MulComplexLeft<T: NumKernel>:
260 Mul<T::RealType, Output = T::ComplexType>
261 + for<'a> Mul<&'a T::RealType, Output = T::ComplexType>
262 + MulAssign<T::RealType>
263 + for<'a> MulAssign<&'a T::RealType>
264{
265}
266
267pub trait MulComplexRight<T: NumKernel>: Mul<T::ComplexType, Output = T::ComplexType> {}
275
276impl Arithmetic for f64 {}
277impl Arithmetic for Complex<f64> {}
278impl MulComplexRight<Native64> for f64 {}
279impl MulComplexLeft<Native64> for Complex<f64> {}
280
281#[cfg(feature = "rug")]
283impl Arithmetic for rug::Float {}
284
285#[cfg(feature = "rug")]
287impl Arithmetic for rug::Complex {}
288
289#[derive(Debug, Clone, PartialEq, PartialOrd)]
296pub struct Native64;
297
298#[cfg(feature = "rug")]
300#[derive(Debug, Clone, PartialEq, PartialOrd)]
306pub struct Rug<const PRECISION: u32>;
307
308pub trait NumKernel: Clone + fmt::Debug + PartialEq + Sync {
310 type RawRealType: Sized + fmt::Debug + RealValueValidator + PartialOrd<f64>;
311 type RawComplexType: Sized + fmt::Debug + ComplexValueValidator<RealType = Self::RawRealType>;
312
313 type RealType: FunctionsRealType<Self> + Serialize + DeserializeOwned;
315
316 type ComplexType: FunctionsComplexType<Self> + Serialize + DeserializeOwned;
318}
319
320impl NumKernel for Native64 {
322 type RawRealType = f64;
323 type RawComplexType = Complex<f64>;
324
325 type RealType = f64;
327
328 type ComplexType = Complex<f64>;
330}
331
332#[cfg(feature = "rug")]
334impl<const PRECISION: u32> NumKernel for Rug<PRECISION> {
335 type RawRealType = rug::Float;
336 type RawComplexType = rug::Complex;
337
338 type RealType = RealRug<PRECISION>;
340
341 type ComplexType = ComplexRug<PRECISION>;
343}
344
345#[duplicate::duplicate_item(
349 trait_name func_name trait_comment func_comment;
350 [ACos] [acos_] ["This trait provides the interface for the *inverse cosine* function."] ["Computes the *inverse cosine* of `self`, rounding to the nearest."];
351 [ASin] [asin_] ["This trait provides the interface for the *inverse sine* function."] ["Computes the *inverse sine* of `self`, rounding to the nearest."];
352 [ATan] [atan_] ["This trait provides the interface for the *inverse tangent* function."] ["Computes the *inverse tangent* of `self`, rounding to the nearest."];
353 [Cos] [cos_] ["This trait provides the interface for the *cosine* function."] ["Computes the *cosine* of `self`, rounding to the nearest."];
354 [Sin] [sin_] ["This trait provides the interface for the *sine* function."] ["Computes the *sine* of `self`, rounding to the nearest."];
355 [Tan] [tan_] ["This trait provides the interface for the *tangent* function."] ["Computes the *tangent* of `self`, rounding to the nearest."];
356 [ACosH] [acosh_] ["This trait provides the interface for the *inverse hyperbolic cosine* function."] ["Computes the *inverse hyperbolic cosine* of `self`, rounding to the nearest."];
357 [ASinH] [asinh_] ["This trait provides the interface for the *inverse hyperbolic* function."] ["Computes the *inverse hyperbolic sine* of `self`, rounding to the nearest."];
358 [ATanH] [atanh_] ["This trait provides the interface for the *inverse hyperbolic tangent* function."] ["Computes the *inverse hyperbolic tangent* of `self`, rounding to the nearest."];
359 [CosH] [cosh_] ["This trait provides the interface for the *hyperbolic cosine* function."] ["Computes the *hyperbolic cosine* of `self`, rounding to the nearest."];
360 [SinH] [sinh_] ["This trait provides the interface for the *hyperbolic sine* function."] ["Computes the *hyperbolic sine* of `self`, rounding to the nearest."];
361 [TanH] [tanh_] ["This trait provides the interface for the *hyperbolic tangent* function."] ["Computes the *tangent* of `self`, rounding to the nearest."];
362 [Exp] [exp_] ["This trait provides the interface for the *exponential* function."] ["Computes `e^(self)`, rounding to the nearest."];
363 [Ln] [ln_] ["This trait provides the interface for the [*natural logarithm*](https://en.wikipedia.org/wiki/Natural_logarithm) function."] ["Computes the [*natural logarithm*](https://en.wikipedia.org/wiki/Natural_logarithm) of `self`, rounding to the nearest."];
364 [Log10] [log10_] ["This trait provides the interface for the [*common logarithm*](https://en.wikipedia.org/wiki/Common_logarithm) function."] ["Computes the [*common logarithm*](https://en.wikipedia.org/wiki/Common_logarithm) of `self`, rounding to the nearest."];
365 [Log2] [log2_] ["This trait provides the interface for the *base 2 logarithm* function."] ["Computes the *base 2 logarithm* of `self`, rounding to the nearest."];
366)]
367#[doc = trait_comment]
368pub trait trait_name {
369 #[doc = func_comment]
370 fn func_name(self) -> Self;
371}
372
373#[duplicate::duplicate_item(
374 trait_name func_name implementation T func_comment;
375 duplicate!{
376 [
377 T_nested; [f64]; [Complex::<f64>]
378 ]
379 [ACos] [acos_] [acos(self)] [T_nested] ["Computes the *inverse cosine* of `self`, rounding to the nearest."];
380 [ASin] [asin_] [asin(self)] [T_nested] ["Computes the *inverse sine* of `self`, rounding to the nearest."];
381 [ATan] [atan_] [atan(self)] [T_nested] ["Computes the *inverse tangent* of `self`, rounding to the nearest."];
382 [Cos] [cos_] [cos(self)] [T_nested] ["Computes the *cosine* of `self`, rounding to the nearest."];
383 [Sin] [sin_] [sin(self)] [T_nested] ["Computes the *sine* of `self`, rounding to the nearest."];
384 [Tan] [tan_] [tan(self)] [T_nested] ["Computes the *tangent* of `self`, rounding to the nearest."];
385 [ACosH] [acosh_] [acosh(self)] [T_nested] ["Computes the *inverse hyperbolic cosine* of `self`, rounding to the nearest."];
386 [ASinH] [asinh_] [asinh(self)] [T_nested] ["Computes the *inverse hyperbolic sine* of `self`, rounding to the nearest."];
387 [ATanH] [atanh_] [atanh(self)] [T_nested] ["Computes the *inverse hyperbolic tangent* of `self`, rounding to the nearest."];
388 [CosH] [cosh_] [cosh(self)] [T_nested] ["Computes the *hyperbolic cosine* of `self`, rounding to the nearest."];
389 [SinH] [sinh_] [sinh(self)] [T_nested] ["Computes the *hyperbolic sine* of `self`, rounding to the nearest."];
390 [TanH] [tanh_] [tanh(self)] [T_nested] ["Computes the *hyperbolic tangent* of `self`, rounding to the nearest."];
391 [Exp] [exp_] [exp(self)] [T_nested] ["Computes `e^(self)`, rounding to the nearest."];
392 [Ln] [ln_] [ln(self)] [T_nested] ["Computes the [*natural logarithm*](https://en.wikipedia.org/wiki/Natural_logarithm) of `self`, rounding to the nearest."];
393 [Log10] [log10_] [log10(self)] [T_nested] ["Computes the [*common logarithm*](https://en.wikipedia.org/wiki/Common_logarithm) of `self`, rounding to the nearest."];
394 [Log2] [log2_] [log2(self)] [T_nested] ["Computes the *base 2 logarithm* of `self`, rounding to the nearest."];
395 }
396)]
397impl trait_name for T {
398 #[doc = func_comment]
399 #[inline(always)]
400 fn func_name(self) -> Self {
401 T::implementation
402 }
403}
404
405#[cfg(feature = "rug")]
406#[duplicate_item(
407 trait_name func_name implementation T func_comment;
408 duplicate!{
409 [
410 T_nested; [RealRug<PRECISION>]; [ComplexRug<PRECISION>]
411 ]
412 [ACos] [acos_] [self.0.acos()] [T_nested] ["Computes the *inverse cosine* of `self`, rounding to the nearest."];
413 [ASin] [asin_] [self.0.asin()] [T_nested] ["Computes the *inverse sine* of `self`, rounding to the nearest."];
414 [ATan] [atan_] [self.0.atan()] [T_nested] ["Computes the *inverse tangent* of `self`, rounding to the nearest."];
415 [Cos] [cos_] [self.0.cos()] [T_nested] ["Computes the *cosine* of `self`, rounding to the nearest."];
416 [Sin] [sin_] [self.0.sin()] [T_nested] ["Computes the *sine* of `self`, rounding to the nearest."];
417 [Tan] [tan_] [self.0.tan()] [T_nested] ["Computes the *tangent* of `self`, rounding to the nearest."];
418 [ACosH] [acosh_] [self.0.acosh()] [T_nested] ["Computes the *inverse hyperbolic cosine* of `self`, rounding to the nearest."];
419 [ASinH] [asinh_] [self.0.asinh()] [T_nested] ["Computes the *inverse hyperbolic sine* of `self`, rounding to the nearest."];
420 [ATanH] [atanh_] [self.0.atanh()] [T_nested] ["Computes the *inverse hyperbolic tangent* of `self`, rounding to the nearest."];
421 [CosH] [cosh_] [self.0.cosh()] [T_nested] ["Computes the *hyperbolic cosine* of `self`, rounding to the nearest."];
422 [SinH] [sinh_] [self.0.sinh()] [T_nested] ["Computes the *hyperbolic sine* of `self`, rounding to the nearest."];
423 [TanH] [tanh_] [self.0.tanh()] [T_nested] ["Computes the *hyperbolic tangent* of `self`, rounding to the nearest."];
424 [Exp] [exp_] [self.0.exp()] [T_nested] ["Computes `e^(self)`, rounding to the nearest."];
425 [Ln] [ln_] [self.0.ln()] [T_nested] ["Computes the [*natural logarithm*](https://en.wikipedia.org/wiki/Natural_logarithm) of `self`, rounding to the nearest."];
426 [Log10] [log10_] [self.0.log10()] [T_nested] ["Computes the [*common logarithm*](https://en.wikipedia.org/wiki/Common_logarithm) of `self`, rounding to the nearest."];
427 }
428)]
429impl<const PRECISION: u32> trait_name for T {
430 #[doc = func_comment]
431 #[inline(always)]
432 fn func_name(self) -> Self {
433 Self(implementation)
434 }
435}
436
437#[cfg(feature = "rug")]
438impl<const PRECISION: u32> Log2 for RealRug<PRECISION> {
439 #[inline(always)]
441 fn log2_(self) -> Self {
442 Self(self.0.log2())
443 }
444}
445
446#[cfg(feature = "rug")]
447impl<const PRECISION: u32> Log2 for ComplexRug<PRECISION> {
448 #[inline(always)]
450 fn log2_(self) -> Self {
451 Self(rug::Complex::with_val(
452 PRECISION,
453 self.0.log10() / rug::Float::with_val(PRECISION, 2.).log10(),
454 ))
455 }
456}
457pub trait TrigonometricFunctions: ACos + ASin + ATan + Sin + Cos + Tan {}
461impl TrigonometricFunctions for f64 {}
462impl TrigonometricFunctions for Complex<f64> {}
463
464#[cfg(feature = "rug")]
465impl<const PRECISION: u32> TrigonometricFunctions for RealRug<PRECISION> {}
466
467#[cfg(feature = "rug")]
468impl<const PRECISION: u32> TrigonometricFunctions for ComplexRug<PRECISION> {}
469pub trait HyperbolicFunctions: ACosH + ASinH + ATanH + SinH + CosH + TanH {}
473impl HyperbolicFunctions for f64 {}
474impl HyperbolicFunctions for Complex<f64> {}
475
476#[cfg(feature = "rug")]
477impl<const PRECISION: u32> HyperbolicFunctions for RealRug<PRECISION> {}
478
479#[cfg(feature = "rug")]
480impl<const PRECISION: u32> HyperbolicFunctions for ComplexRug<PRECISION> {}
481#[duplicate::duplicate_item(
485 trait_name func_name trait_comment func_comment;
486 [IsFinite] [is_finite_] ["This trait provides the interface for the function used to check if a number is finite (i.e. neither infinite or NaN)."] ["Returns `true` if `self` is neither infinite nor NaN."];
487 [IsInfinite] [is_infinite_] ["This trait provides the interface for the function used to check if a number is infinite."] ["Returns `true` if `self` is positive infinity or negative infinity."];
488 [IsNaN] [is_nan_] ["This trait provides the interface for the function used to check if a value is NaN."] ["Returns `true` if `self` is NaN."];
489 [IsNormal] [is_normal_] ["This trait provides the interface for the function used to check if a number is *normal* (i.e. neither zero, infinite, subnormal, or NaN)."] ["Returns `true` if `self` is *normal* (i.e. neither zero, infinite, subnormal, or NaN)."];
490 [IsSubnormal] [is_subnormal_] ["This trait provides the interface for the function used to check if a number is *sub-normal*."] ["Returns `true` if `self` is *sub-normal*."];
491)]
492#[doc = trait_comment]
493pub trait trait_name {
494 #[doc = func_comment]
495 fn func_name(&self) -> bool;
496}
497
498#[duplicate::duplicate_item(
499 trait_name func_name implementation T func_comment;
500 duplicate!{
501 [
502 T_nested; [f64]; [Complex<f64>]
503 ]
504 [IsFinite] [is_finite_] [self.is_finite()] [T_nested] ["Returns `true` if `self` is neither infinite nor NaN."];
505 [IsInfinite] [is_infinite_] [self.is_infinite()] [T_nested] ["Returns `true` if `self` is positive infinity or negative infinity, and `false` otherwise."];
506 [IsNaN] [is_nan_] [self.is_nan()] [T_nested] ["Returns `true` if `self` is NaN."];
507 [IsNormal] [is_normal_] [self.is_normal()] [T_nested] ["Returns `true` if `self` is *normal* (i.e. neither zero, infinite, subnormal, or NaN)."];
508 }
509)]
510impl trait_name for T {
511 #[doc = func_comment]
512 #[inline(always)]
513 fn func_name(&self) -> bool {
514 implementation
515 }
516}
517
518impl IsSubnormal for f64 {
519 #[inline(always)]
521 fn is_subnormal_(&self) -> bool {
522 self.classify() == FpCategory::Subnormal
523 }
524}
525
526impl IsSubnormal for Complex<f64> {
527 #[inline(always)]
529 fn is_subnormal_(&self) -> bool {
530 self.re.classify() == FpCategory::Subnormal || self.im.classify() == FpCategory::Subnormal
531 }
532}
533
534#[cfg(feature = "rug")]
535#[duplicate::duplicate_item(
536 trait_name func_name implementation func_comment;
537 [IsFinite] [is_finite_] [self.0.is_finite()] ["Returns `true` if `self` is neither infinite nor NaN."];
538 [IsInfinite] [is_infinite_] [self.0.is_infinite()] ["Returns `true` if `self` is positive infinity or negative infinity, and `false` otherwise."];
539 [IsNaN] [is_nan_] [self.0.is_nan()] ["Returns `true` if `self` is NaN."];
540 [IsNormal] [is_normal_] [self.0.is_normal()] ["Returns `true` if `self` is *normal* (i.e. neither zero, infinite, subnormal, or NaN)."];
541 [IsSubnormal] [is_subnormal_] [self.0.classify() == FpCategory::Subnormal] ["Returns `true` if `self` is *sub-normal*."];
542)]
543impl<const PRECISION: u32> trait_name for RealRug<PRECISION> {
544 #[doc = func_comment]
545 #[inline(always)]
546 fn func_name(&self) -> bool {
547 implementation
548 }
549}
550
551#[cfg(feature = "rug")]
552impl<const PRECISION: u32> IsFinite for ComplexRug<PRECISION> {
553 #[inline(always)]
555 fn is_finite_(&self) -> bool {
556 self.0.real().is_finite() && self.0.imag().is_finite()
557 }
558}
559
560#[cfg(feature = "rug")]
561impl<const PRECISION: u32> IsInfinite for ComplexRug<PRECISION> {
562 #[inline(always)]
564 fn is_infinite_(&self) -> bool {
565 self.0.real().is_infinite() || self.0.imag().is_infinite()
566 }
567}
568
569#[cfg(feature = "rug")]
570impl<const PRECISION: u32> IsNaN for ComplexRug<PRECISION> {
571 #[inline(always)]
573 fn is_nan_(&self) -> bool {
574 self.0.real().is_nan() || self.0.imag().is_nan()
575 }
576}
577
578#[cfg(feature = "rug")]
579impl<const PRECISION: u32> IsNormal for ComplexRug<PRECISION> {
580 #[inline(always)]
582 fn is_normal_(&self) -> bool {
583 self.0.real().is_normal() && self.0.imag().is_normal()
584 }
585}
586
587#[cfg(feature = "rug")]
588impl<const PRECISION: u32> IsSubnormal for ComplexRug<PRECISION> {
589 #[inline(always)]
591 fn is_subnormal_(&self) -> bool {
592 self.0.real().classify() == FpCategory::Subnormal
593 || self.0.imag().classify() == FpCategory::Subnormal
594 }
595}
596pub trait FpChecks: IsFinite + IsInfinite + IsNaN + IsNormal + IsSubnormal {}
600impl FpChecks for f64 {}
601impl FpChecks for Complex<f64> {}
602
603#[cfg(feature = "rug")]
604impl<const PRECISION: u32> FpChecks for RealRug<PRECISION> {}
605
606#[cfg(feature = "rug")]
607impl<const PRECISION: u32> FpChecks for ComplexRug<PRECISION> {}
608#[cfg(feature = "rug")]
612impl<const PRECISION: u32> Zero for RealRug<PRECISION> {
613 fn zero() -> Self {
615 Self(rug::Float::with_val(PRECISION, 0.))
616 }
617
618 fn is_zero(&self) -> bool {
620 self.0.is_zero()
621 }
622}
623
624#[cfg(feature = "rug")]
625impl<const PRECISION: u32> Zero for ComplexRug<PRECISION> {
626 fn zero() -> Self {
628 Self(rug::Complex::with_val(PRECISION, (0., 0.)))
629 }
630
631 fn is_zero(&self) -> bool {
633 self.0.is_zero()
634 }
635}
636#[cfg(feature = "rug")]
640impl<const PRECISION: u32> One for RealRug<PRECISION> {
641 fn one() -> Self {
643 Self(rug::Float::with_val(PRECISION, 1.))
644 }
645}
646pub trait MulAdd {
655 fn mul_add(self, b: &Self, c: &Self) -> Self;
659}
660
661#[duplicate::duplicate_item(
662 T trait_comment;
663 [f64] ["Implementation of the [`MulAdd`] trait for `f64`."];
664 [Complex<f64>] ["Implementation of the [`MulAdd`] trait for `Complex<f64>`."];
665)]
666#[doc = trait_comment]
667impl MulAdd for T {
668 #[inline(always)]
672 fn mul_add(self, b: &Self, c: &Self) -> Self {
673 <Self as num::traits::MulAdd>::mul_add(self, *b, *c)
674 }
675}
676
677#[cfg(feature = "rug")]
678#[duplicate::duplicate_item(
679 T trait_comment;
680 [RealRug<PRECISION>] ["Implementation of the [`MulAdd`] trait for [`RealRug`]."];
681 [ComplexRug<PRECISION>] ["Implementation of the [`MulAdd`] trait for [`ComplexRug`]."];
682)]
683#[doc = trait_comment]
684impl<const PRECISION: u32> MulAdd for T {
685 #[inline(always)]
689 fn mul_add(self, b: &Self, c: &Self) -> Self {
690 Self(self.0.mul_add(&b.0, &c.0))
691 }
692}
693pub trait FunctionsGeneralType<T: NumKernel>:
698 Clone
699 + fmt::Debug
700 + fmt::Display
701 + Arithmetic
702 + Sqrt
703 + PowTrait<T>
704 + TrigonometricFunctions
705 + HyperbolicFunctions
706 + Exp
707 + Ln
708 + Log10
709 + Log2
710 + Zero
711 + Abs<Output = T::RealType>
712 + FpChecks
713 + Neg<Output = Self>
714 + MulAdd
715 + Reciprocal
716 + Send
717 + Sync
718{
719}
720pub trait TryNew: Sized {
724 type ValueType;
725 type Error;
726
727 fn try_new(value: Self::ValueType) -> Result<Self, Self::Error>;
728
729 fn new(value: Self::ValueType) -> Self;
730}
731
732impl TryNew for f64 {
733 type ValueType = f64;
734 type Error = RealValueErrors<f64>;
735
736 #[inline(always)]
737 fn try_new(value: Self::ValueType) -> Result<Self, Self::Error> {
738 value.validate()
739 }
740
741 #[inline(always)]
742 fn new(value: Self::ValueType) -> Self {
743 if cfg!(debug_assertions) {
744 Self::try_new(value).unwrap()
745 } else {
746 value
747 }
748 }
749}
750
751impl TryNew for Complex<f64> {
752 type ValueType = Complex<f64>;
753 type Error = ComplexValueErrors<f64, Complex<f64>>;
754
755 #[inline(always)]
756 fn try_new(value: Self::ValueType) -> Result<Self, Self::Error> {
757 value.validate()
758 }
759
760 #[inline(always)]
761 fn new(value: Self::ValueType) -> Self {
762 if cfg!(debug_assertions) {
763 Self::try_new(value).unwrap()
764 } else {
765 value
766 }
767 }
768}
769
770#[cfg(feature = "rug")]
771impl<const PRECISION: u32> TryNew for RealRug<PRECISION> {
772 type ValueType = rug::Float;
773 type Error = RealValueErrors<rug::Float>;
774
775 #[inline(always)]
776 fn try_new(value: Self::ValueType) -> Result<Self, Self::Error> {
777 assert_eq!(value.prec(), PRECISION,
778 "The precision of the numerical kernel ({PRECISION}) and is different from the precision of the input value ({})!",value.prec());
779
780 let value = value.validate()?;
781 Ok(Self(value))
782 }
783
784 #[inline(always)]
785 fn new(value: Self::ValueType) -> Self {
786 if cfg!(debug_assertions) {
787 Self::try_new(value).unwrap()
788 } else {
789 Self(value)
790 }
791 }
792}
793
794#[cfg(feature = "rug")]
795impl<const PRECISION: u32> TryNew for ComplexRug<PRECISION> {
796 type ValueType = rug::Complex;
797 type Error = ComplexValueErrors<rug::Float, rug::Complex>;
798
799 #[inline(always)]
800 fn try_new(value: Self::ValueType) -> Result<Self, Self::Error> {
801 assert_eq!(value.prec(), (PRECISION, PRECISION),
802 "The precision of the numerical kernel ({PRECISION}) and is different from the precision of the input value ({:?})!",value.prec());
803
804 let value = value.validate()?;
805 Ok(Self(value))
806 }
807
808 #[inline(always)]
809 fn new(value: Self::ValueType) -> Self {
810 if cfg!(debug_assertions) {
811 Self::try_new(value).unwrap()
812 } else {
813 Self(value)
814 }
815 }
816}
817
818pub trait FunctionsRealType<T: NumKernel>:
823 FunctionsGeneralType<T>
824 + PartialEq
825 + PartialEq<f64>
826 + PartialOrd
827 + PartialOrd<f64>
828 + MulComplexRight<T>
829 + One
830{
831 fn atan2_(self, other: &Self) -> Self;
837
838 fn ceil_(self) -> Self;
840
841 fn clamp_(self, min: &Self, max: &Self) -> Self;
859
860 fn classify_(&self) -> FpCategory;
873
874 fn copysign_(self, sign: &Self) -> Self;
876
877 fn epsilon_() -> Self;
883
884 fn exp_m1_(self) -> Self;
886
887 fn floor_(self) -> Self;
889
890 fn fract_(self) -> Self;
892
893 fn hypot_(self, other: &Self) -> Self;
896
897 fn infinity_() -> Self;
899
900 fn is_sign_negative_(&self) -> bool;
902
903 fn is_sign_positive_(&self) -> bool;
905
906 fn ln_1p_(self) -> Self;
908
909 fn neg_infinity_() -> Self;
911
912 fn max_(self, other: &Self) -> Self;
914
915 fn min_(self, other: &Self) -> Self;
917
918 fn mul_add_mul_mut_(&mut self, mul: &Self, add_mul1: &Self, add_mul2: &Self);
921
922 fn mul_sub_mul_mut_(&mut self, mul: &Self, sub_mul1: &Self, sub_mul2: &Self);
925
926 fn negative_one_() -> Self;
928
929 fn one_div_2_() -> Self;
931
932 fn pi_() -> Self {
934 Self::negative_one_().acos_()
935 }
936
937 fn pi_div_2_() -> Self {
939 Self::one().asin_()
940 }
941
942 fn round_(self) -> Self;
944
945 fn round_ties_even_(self) -> Self;
964
965 fn signum_(self) -> Self;
972
973 fn total_cmp_(&self, other: &Self) -> Ordering;
974
975 fn try_from_f64_(value: f64) -> Result<Self, TryFromf64Errors>;
979
980 fn trunc_(self) -> Self;
995
996 fn two_() -> Self;
998}
999
1000pub trait FunctionsComplexType<T: NumKernel>:
1002 FunctionsGeneralType<T> + PartialEq + MulComplexLeft<T>
1003{
1004 fn arg_(self) -> T::RealType;
1006
1007 fn new_(real_part: T::RealType, imag_part: T::RealType) -> Self;
1009
1010 fn real_(&self) -> T::RealType;
1012
1013 fn imag_(&self) -> T::RealType;
1015
1016 fn set_real_(&mut self, real_part: T::RealType);
1018
1019 fn set_imag_(&mut self, imag_part: T::RealType);
1021
1022 fn add_real_(&mut self, c: &T::RealType);
1024
1025 fn add_imag_(&mut self, c: &T::RealType);
1027
1028 fn multiply_real_(&mut self, c: &T::RealType);
1030
1031 fn multiply_imag_(&mut self, c: &T::RealType);
1033
1034 fn conj_(self) -> Self;
1036
1037 fn try_from_f64_(real_part: f64, imag_part: f64) -> Result<Self, TryFromf64Errors>;
1041}
1042
1043impl FunctionsGeneralType<Native64> for f64 {}
1044
1045impl FunctionsGeneralType<Native64> for Complex<f64> {}
1046
1047impl FunctionsRealType<Native64> for f64 {
1048 #[inline(always)]
1063 fn atan2_(self, other: &Self) -> Self {
1064 self.atan2(*other)
1065 }
1066
1067 #[inline(always)]
1069 fn ceil_(self) -> Self {
1070 self.ceil()
1071 }
1072
1073 #[inline(always)]
1091 fn clamp_(self, min: &Self, max: &Self) -> Self {
1092 self.clamp(*min, *max)
1093 }
1094
1095 #[inline(always)]
1108 fn classify_(&self) -> FpCategory {
1109 self.classify()
1110 }
1111
1112 #[inline(always)]
1114 fn copysign_(self, sign: &Self) -> Self {
1115 self.copysign(*sign)
1116 }
1117
1118 #[inline(always)]
1124 fn epsilon_() -> Self {
1125 f64::EPSILON
1126 }
1127
1128 #[inline(always)]
1130 fn exp_m1_(self) -> Self {
1131 self.exp_m1()
1132 }
1133
1134 #[inline(always)]
1136 fn floor_(self) -> Self {
1137 self.floor()
1138 }
1139
1140 #[inline(always)]
1142 fn fract_(self) -> Self {
1143 self.fract()
1144 }
1145
1146 #[inline(always)]
1149 fn hypot_(self, other: &Self) -> Self {
1150 self.hypot(*other)
1151 }
1152
1153 #[inline(always)]
1155 fn infinity_() -> Self {
1156 f64::INFINITY
1157 }
1158
1159 #[inline(always)]
1161 fn is_sign_negative_(&self) -> bool {
1162 self.is_sign_negative()
1163 }
1164
1165 #[inline(always)]
1167 fn is_sign_positive_(&self) -> bool {
1168 self.is_sign_positive()
1169 }
1170
1171 #[inline(always)]
1173 fn ln_1p_(self) -> Self {
1174 self.ln_1p()
1175 }
1176
1177 #[inline(always)]
1179 fn neg_infinity_() -> Self {
1180 f64::NEG_INFINITY
1181 }
1182
1183 #[inline(always)]
1185 fn max_(self, other: &Self) -> Self {
1186 self.max(*other)
1187 }
1188
1189 #[inline(always)]
1191 fn min_(self, other: &Self) -> Self {
1192 self.min(*other)
1193 }
1194
1195 #[inline(always)]
1198 fn mul_add_mul_mut_(&mut self, mul: &Self, add_mul1: &Self, add_mul2: &Self) {
1199 self.mul_add_assign(*mul, add_mul1 * add_mul2);
1200 }
1201
1202 #[inline(always)]
1205 fn mul_sub_mul_mut_(&mut self, mul: &Self, sub_mul1: &Self, sub_mul2: &Self) {
1206 self.mul_add_assign(*mul, -sub_mul1 * sub_mul2);
1207 }
1208
1209 #[inline(always)]
1211 fn negative_one_() -> Self {
1212 -1.
1213 }
1214
1215 #[inline(always)]
1217 fn one_div_2_() -> Self {
1218 0.5
1219 }
1220
1221 #[inline(always)]
1223 fn round_(self) -> Self {
1224 self.round()
1225 }
1226
1227 #[inline(always)]
1246 fn round_ties_even_(self) -> Self {
1247 self.round_ties_even()
1248 }
1249
1250 #[inline(always)]
1257 fn signum_(self) -> Self {
1258 self.signum()
1259 }
1260
1261 #[inline(always)]
1262 fn total_cmp_(&self, other: &Self) -> Ordering {
1263 self.total_cmp(other)
1264 }
1265
1266 #[inline(always)]
1270 fn try_from_f64_(value: f64) -> Result<Self, TryFromf64Errors> {
1271 match value.validate() {
1272 Ok(value) => Ok(value),
1273 Err(e) => Err(TryFromf64Errors::ValidationError { source: e }),
1274 }
1275 }
1276
1277 #[inline(always)]
1292 fn trunc_(self) -> Self {
1293 self.trunc()
1294 }
1295
1296 #[inline(always)]
1298 fn two_() -> Self {
1299 2.
1300 }
1301}
1302
1303impl IntoInner for Complex<f64> {
1305 type Target = (f64, f64);
1307
1308 #[inline(always)]
1310 fn into_inner(self) -> Self::Target {
1311 (self.re, self.im)
1312 }
1313}
1314
1315impl FunctionsComplexType<Native64> for Complex<f64> {
1317 #[inline(always)]
1319 fn arg_(self) -> f64 {
1320 self.arg()
1321 }
1322
1323 #[inline(always)]
1328 fn new_(real_part: f64, imag_part: f64) -> Self {
1329 debug_assert!(
1330 real_part.is_finite(),
1331 "The real part is not finite (i.e. is infinite or NaN)."
1332 );
1333 debug_assert!(
1334 imag_part.is_finite(),
1335 "The imaginary part is not finite (i.e. is infinite or NaN)."
1336 );
1337 Complex::new(real_part, imag_part)
1338 }
1339
1340 #[inline(always)]
1342 fn real_(&self) -> f64 {
1343 self.re
1344 }
1345
1346 #[inline(always)]
1348 fn imag_(&self) -> f64 {
1349 self.im
1350 }
1351
1352 #[inline(always)]
1357 fn set_real_(&mut self, real_part: f64) {
1358 debug_assert!(
1359 real_part.is_finite(),
1360 "The real part is not finite (i.e. is infinite or NaN)."
1361 );
1362 self.re = real_part;
1363 }
1364
1365 #[inline(always)]
1370 fn set_imag_(&mut self, imag_part: f64) {
1371 debug_assert!(
1372 imag_part.is_finite(),
1373 "The imaginary part is not finite (i.e. is infinite or NaN)."
1374 );
1375 self.im = imag_part;
1376 }
1377
1378 #[inline(always)]
1380 fn add_real_(&mut self, c: &f64) {
1381 self.re += c;
1382
1383 debug_assert!(
1384 self.re.is_finite(),
1385 "The real part is not finite (i.e. is infinite or NaN)."
1386 );
1387 }
1388
1389 #[inline(always)]
1391 fn add_imag_(&mut self, c: &f64) {
1392 self.im += c;
1393
1394 debug_assert!(
1395 self.im.is_finite(),
1396 "The imaginary part is not finite (i.e. is infinite or NaN)."
1397 );
1398 }
1399
1400 #[inline(always)]
1402 fn multiply_real_(&mut self, c: &f64) {
1403 self.re *= c;
1404
1405 debug_assert!(
1406 self.re.is_finite(),
1407 "The real part is not finite (i.e. is infinite or NaN)."
1408 );
1409 }
1410
1411 #[inline(always)]
1413 fn multiply_imag_(&mut self, c: &f64) {
1414 self.im *= c;
1415
1416 debug_assert!(
1417 self.im.is_finite(),
1418 "The imaginary part is not finite (i.e. is infinite or NaN)."
1419 );
1420 }
1421
1422 #[inline(always)]
1424 fn conj_(self) -> Self {
1425 self.conj()
1426 }
1427
1428 #[inline(always)]
1432 fn try_from_f64_(real_part: f64, imag_part: f64) -> Result<Self, TryFromf64Errors> {
1433 let real_part = <f64 as FunctionsRealType<Native64>>::try_from_f64_(real_part)?;
1434 let imag_part = <f64 as FunctionsRealType<Native64>>::try_from_f64_(imag_part)?;
1435
1436 Ok(Complex::new(real_part, imag_part))
1437 }
1438}
1439
1440#[cfg(feature = "rug")]
1445#[derive(
1446 Add,
1447 AddAssign,
1448 AsRef,
1449 Clone,
1450 Debug,
1451 Deserialize,
1452 Display,
1453 Div,
1454 DivAssign,
1455 LowerExp,
1456 Mul,
1457 MulAssign,
1458 Neg,
1459 PartialEq,
1460 PartialOrd,
1461 Serialize,
1462 Sub,
1463 SubAssign,
1464)]
1465#[mul(forward)]
1466#[mul_assign(forward)]
1467#[div(forward)]
1468#[div_assign(forward)]
1469pub struct RealRug<const PRECISION: u32>(rug::Float);
1470
1471#[cfg(feature = "rug")]
1473impl<const PRECISION: u32> RealRug<PRECISION> {
1474 #[inline(always)]
1475 pub fn new(value: rug::Float) -> Self {
1476 debug_assert!(value.is_finite(), "Not a finite number!");
1477 debug_assert_eq!(
1478 value.prec(),
1479 PRECISION,
1480 "The input value must have a precision = {PRECISION}, but actually has precision = {}",
1481 value.prec()
1482 );
1483 Self(value)
1484 }
1485}
1486
1487#[cfg(feature = "rug")]
1489#[derive(
1490 Add,
1491 AddAssign,
1492 AsRef,
1493 Clone,
1494 Debug,
1495 Deserialize,
1496 Display,
1497 Div,
1498 DivAssign,
1499 LowerExp,
1500 Mul,
1501 MulAssign,
1502 Neg,
1503 PartialEq,
1504 Serialize,
1505 Sub,
1506 SubAssign,
1507)]
1508#[mul(forward)]
1509#[mul_assign(forward)]
1510#[div(forward)]
1511#[div_assign(forward)]
1512pub struct ComplexRug<const PRECISION: u32>(rug::Complex);
1513
1514#[cfg(feature = "rug")]
1516impl<const PRECISION: u32> ComplexRug<PRECISION> {
1517 #[inline(always)]
1518 pub fn new(value: rug::Complex) -> Self {
1519 debug_assert!(
1520 value.real().is_finite() && value.imag().is_finite(),
1521 "Not a finite number!"
1522 );
1523 debug_assert_eq!(
1524 value.prec(),
1525 (PRECISION, PRECISION),
1526 "The input value must have a precision = {:?}, but actually has precision = {:?}",
1527 (PRECISION, PRECISION),
1528 value.prec()
1529 );
1530 Self(value)
1531 }
1532}
1533
1534#[cfg(feature = "rug")]
1535impl<const PRECISION: u32> IntoInner for ComplexRug<PRECISION> {
1536 type Target = (RealRug<PRECISION>, RealRug<PRECISION>);
1537
1538 #[inline(always)]
1539 fn into_inner(self) -> Self::Target {
1540 (
1541 RealRug::new(self.0.real().clone()),
1542 RealRug::new(self.0.imag().clone()),
1543 )
1544 }
1545}
1546
1547#[cfg(feature = "rug")]
1549#[duplicate_item(
1550 T;
1551 [RealRug<PRECISION>];
1552 [ComplexRug<PRECISION>];
1553)]
1554impl<const PRECISION: u32> NegAssign for T {
1555 #[inline(always)]
1557 fn neg_assign(&mut self) {
1558 rug::ops::NegAssign::neg_assign(&mut self.0);
1559 }
1560}
1561
1562#[cfg(feature = "rug")]
1564#[duplicate_item(
1565 trait_name method T;
1566 duplicate!{
1567 [
1568 rug_type;[RealRug];[ComplexRug]
1569 ]
1570 [Add] [add] [rug_type];
1571 [Sub] [sub] [rug_type];
1572 [Mul] [mul] [rug_type];
1573 }
1574)]
1575impl<'a, const PRECISION: u32> trait_name<&'a T<PRECISION>> for T<PRECISION> {
1576 type Output = T<PRECISION>;
1577
1578 #[inline(always)]
1579 fn method(self, rhs: &'a T<PRECISION>) -> Self::Output {
1580 T(self.0.method(&rhs.0))
1581 }
1582}
1583
1584#[cfg(feature = "rug")]
1586#[duplicate_item(
1587 trait_name method T;
1588 duplicate!{
1589 [
1590 rug_type;[RealRug];[ComplexRug]
1591 ]
1592 [Add] [add] [rug_type];
1593 [Sub] [sub] [rug_type];
1594 [Mul] [mul] [rug_type];
1595 }
1596)]
1597impl<'a, const PRECISION: u32> trait_name<T<PRECISION>> for &T<PRECISION> {
1598 type Output = T<PRECISION>;
1599
1600 #[inline(always)]
1601 fn method(self, rhs: T<PRECISION>) -> Self::Output {
1602 let lhs = &self.0;
1603 T(lhs.method(rhs.0))
1604 }
1605}
1606
1607#[cfg(feature = "rug")]
1609#[duplicate_item(
1610 T;
1611 [RealRug];
1612 [ComplexRug];
1613)]
1614impl<'a, const PRECISION: u32> Div<&'a T<PRECISION>> for T<PRECISION> {
1615 type Output = T<PRECISION>;
1616
1617 #[inline(always)]
1618 fn div(self, rhs: &'a T<PRECISION>) -> Self::Output {
1619 debug_assert!(!rhs.0.is_zero(), "Division by zero!");
1620 T(self.0.div(&rhs.0))
1621 }
1622}
1623
1624#[cfg(feature = "rug")]
1626#[duplicate_item(
1627 T;
1628 [RealRug];
1629 [ComplexRug];
1630)]
1631impl<'a, const PRECISION: u32> Div<T<PRECISION>> for &T<PRECISION> {
1632 type Output = T<PRECISION>;
1633
1634 #[inline(always)]
1635 fn div(self, rhs: T<PRECISION>) -> Self::Output {
1636 debug_assert!(!rhs.0.is_zero(), "Division by zero!");
1637 let lhs = &self.0;
1638 T(lhs.div(rhs.0))
1639 }
1640}
1641
1642#[cfg(feature = "rug")]
1644#[duplicate_item(
1645 trait_name method T;
1646 duplicate!{
1647 [
1648 rug_type;[RealRug];[ComplexRug]
1649 ]
1650 [AddAssign] [add_assign] [rug_type];
1651 [SubAssign] [sub_assign] [rug_type];
1652 [MulAssign] [mul_assign] [rug_type];
1653 }
1654)]
1655impl<'a, const PRECISION: u32> trait_name<&'a T<PRECISION>> for T<PRECISION> {
1656 #[inline(always)]
1657 fn method(&mut self, rhs: &'a T<PRECISION>) {
1658 self.0.method(&rhs.0);
1659 }
1660}
1661
1662#[cfg(feature = "rug")]
1664impl<'a, const PRECISION: u32> Mul<RealRug<PRECISION>> for ComplexRug<PRECISION> {
1665 type Output = ComplexRug<PRECISION>;
1666
1667 #[inline(always)]
1668 fn mul(self, rhs: RealRug<PRECISION>) -> ComplexRug<PRECISION> {
1669 Self(self.0.mul(rhs.0))
1670 }
1671}
1672
1673#[cfg(feature = "rug")]
1675impl<'a, const PRECISION: u32> Mul<&'a RealRug<PRECISION>> for ComplexRug<PRECISION> {
1676 type Output = ComplexRug<PRECISION>;
1677
1678 #[inline(always)]
1679 fn mul(self, rhs: &'a RealRug<PRECISION>) -> ComplexRug<PRECISION> {
1680 Self(self.0.mul(&rhs.0))
1681 }
1682}
1683
1684#[cfg(feature = "rug")]
1686impl<'a, const PRECISION: u32> MulAssign<RealRug<PRECISION>> for ComplexRug<PRECISION> {
1687 #[inline(always)]
1688 fn mul_assign(&mut self, rhs: RealRug<PRECISION>) {
1689 self.0.mul_assign(rhs.0);
1690 }
1691}
1692
1693#[cfg(feature = "rug")]
1695impl<'a, const PRECISION: u32> MulAssign<&'a RealRug<PRECISION>> for ComplexRug<PRECISION> {
1696 #[inline(always)]
1697 fn mul_assign(&mut self, rhs: &'a RealRug<PRECISION>) {
1698 self.0.mul_assign(&rhs.0);
1699 }
1700}
1701
1702#[cfg(feature = "rug")]
1704#[duplicate_item(
1705 T;
1706 [RealRug<PRECISION>];
1707 [ComplexRug<PRECISION>];
1708)]
1709impl<'a, const PRECISION: u32> DivAssign<&'a T> for T {
1710 #[inline(always)]
1711 fn div_assign(&mut self, rhs: &'a T) {
1712 debug_assert!(!rhs.0.is_zero(), "Division by zero!");
1713 self.0.div_assign(&rhs.0);
1714 }
1715}
1716
1717#[cfg(feature = "rug")]
1719impl<const PRECISION: u32> Arithmetic for RealRug<PRECISION> {}
1720
1721#[cfg(feature = "rug")]
1723impl<const PRECISION: u32> Arithmetic for ComplexRug<PRECISION> {}
1724
1725#[cfg(feature = "rug")]
1727#[duplicate::duplicate_item(
1728 exponent_type T;
1729 duplicate!{
1730 [
1731 rug_type;[RealRug<PRECISION>];[ComplexRug<PRECISION>]
1732 ]
1733 [i8] [rug_type];
1734 [u8] [rug_type];
1735 [i16] [rug_type];
1736 [u16] [rug_type];
1737 [i32] [rug_type];
1738 [u32] [rug_type];
1739 [i64] [rug_type];
1740 [u64] [rug_type];
1741 [i128] [rug_type];
1742 [u128] [rug_type];
1743 [usize] [rug_type];
1744 }
1745)]
1746impl<const PRECISION: u32> Pow<exponent_type> for T {
1747 #[inline(always)]
1749 fn pow_(self, exponent: exponent_type) -> Self {
1750 Self(self.0.pow(exponent))
1751 }
1752}
1753
1754#[cfg(feature = "rug")]
1756#[duplicate::duplicate_item(
1757 T;
1758 [RealRug<PRECISION>];
1759 [ComplexRug<PRECISION>];
1760)]
1761impl<const PRECISION: u32> Pow<RealRug<PRECISION>> for T {
1762 #[inline(always)]
1764 fn pow_(self, exponent: RealRug<PRECISION>) -> Self {
1765 Self(self.0.pow(exponent.0))
1766 }
1767}
1768
1769#[cfg(feature = "rug")]
1771impl<const PRECISION: u32> PowTrait<Rug<PRECISION>> for RealRug<PRECISION> {}
1772
1773#[cfg(feature = "rug")]
1775impl<const PRECISION: u32> PowTrait<Rug<PRECISION>> for ComplexRug<PRECISION> {}
1776
1777#[cfg(feature = "rug")]
1779impl<const PRECISION: u32> PartialEq<f64> for RealRug<PRECISION> {
1780 #[inline(always)]
1781 fn eq(&self, other: &f64) -> bool {
1782 self.0.eq(other)
1783 }
1784}
1785
1786#[cfg(feature = "rug")]
1788impl<const PRECISION: u32> PartialOrd<f64> for RealRug<PRECISION> {
1789 #[inline(always)]
1790 fn partial_cmp(&self, other: &f64) -> Option<Ordering> {
1791 self.0.partial_cmp(other)
1792 }
1793}
1794
1795#[cfg(feature = "rug")]
1797impl<const PRECISION: u32> FunctionsGeneralType<Rug<PRECISION>> for RealRug<PRECISION> {}
1798
1799#[cfg(feature = "rug")]
1801impl<const PRECISION: u32> FunctionsRealType<Rug<PRECISION>> for RealRug<PRECISION> {
1802 #[inline(always)]
1822 fn atan2_(self, other: &Self) -> Self {
1823 Self(self.0.atan2(&other.0))
1824 }
1825
1826 #[inline(always)]
1828 fn ceil_(self) -> Self {
1829 Self(self.0.ceil())
1830 }
1831
1832 #[inline(always)]
1834 fn clamp_(self, min: &Self, max: &Self) -> Self {
1835 Self(self.0.clamp(&min.0, &max.0))
1836 }
1837
1838 #[inline(always)]
1853 fn classify_(&self) -> FpCategory {
1854 self.0.classify()
1855 }
1856
1857 #[inline(always)]
1859 fn copysign_(self, sign: &Self) -> Self {
1860 Self(self.0.copysign(&sign.0))
1861 }
1862
1863 #[inline(always)]
1869 fn epsilon_() -> Self {
1870 Self(
1871 rug::Float::u_pow_u(2, PRECISION - 1)
1872 .complete(PRECISION.into())
1873 .recip(),
1874 )
1875 }
1876
1877 #[inline(always)]
1879 fn exp_m1_(self) -> Self {
1880 Self(self.0.exp_m1())
1881 }
1882
1883 #[inline(always)]
1885 fn floor_(self) -> Self {
1886 Self(self.0.floor())
1887 }
1888
1889 #[inline(always)]
1891 fn fract_(self) -> Self {
1892 Self(self.0.fract())
1893 }
1894
1895 #[inline(always)]
1898 fn hypot_(self, other: &Self) -> Self {
1899 Self(self.0.hypot(&other.0))
1900 }
1901
1902 #[inline(always)]
1904 fn infinity_() -> Self {
1905 Self(rug::Float::with_val(
1906 PRECISION,
1907 rug::float::Special::Infinity,
1908 ))
1909 }
1910
1911 #[inline(always)]
1913 fn is_sign_negative_(&self) -> bool {
1914 self.0.is_sign_negative()
1915 }
1916
1917 #[inline(always)]
1919 fn is_sign_positive_(&self) -> bool {
1920 self.0.is_sign_positive()
1921 }
1922
1923 #[inline(always)]
1925 fn ln_1p_(self) -> Self {
1926 Self(self.0.ln_1p())
1927 }
1928
1929 #[inline(always)]
1931 fn neg_infinity_() -> Self {
1932 Self(rug::Float::with_val(
1933 PRECISION,
1934 rug::float::Special::NegInfinity,
1935 ))
1936 }
1937
1938 #[inline(always)]
1940 fn max_(self, other: &Self) -> Self {
1941 Self(self.0.max(&other.0))
1942 }
1943
1944 #[inline(always)]
1946 fn min_(self, other: &Self) -> Self {
1947 Self(self.0.min(&other.0))
1948 }
1949
1950 #[inline(always)]
1953 fn mul_add_mul_mut_(&mut self, mul: &Self, add_mul1: &Self, add_mul2: &Self) {
1954 self.0.mul_add_mul_mut(&mul.0, &add_mul1.0, &add_mul2.0);
1955 }
1956
1957 #[inline(always)]
1960 fn mul_sub_mul_mut_(&mut self, mul: &Self, sub_mul1: &Self, sub_mul2: &Self) {
1961 self.0.mul_sub_mul_mut(&mul.0, &sub_mul1.0, &sub_mul2.0);
1962 }
1963
1964 #[inline(always)]
1966 fn negative_one_() -> Self {
1967 Self(rug::Float::with_val(PRECISION, -1.))
1968 }
1969
1970 #[inline(always)]
1972 fn one_div_2_() -> Self {
1973 Self(rug::Float::with_val(PRECISION, 0.5))
1974 }
1975
1976 #[inline(always)]
1978 fn round_(self) -> Self {
1979 Self(self.0.round())
1980 }
1981
1982 #[inline(always)]
2003 fn round_ties_even_(self) -> Self {
2004 Self(self.0.round_even())
2005 }
2006
2007 #[inline(always)]
2014 fn signum_(self) -> Self {
2015 Self(self.0.signum())
2016 }
2017
2018 #[inline(always)]
2019 fn total_cmp_(&self, other: &Self) -> Ordering {
2020 self.0.total_cmp(&other.0)
2021 }
2022
2023 #[inline(always)]
2027 fn try_from_f64_(value: f64) -> Result<Self, TryFromf64Errors> {
2028 match value.validate() {
2029 Ok(value) => {
2030 let value_rug = rug::Float::with_val(PRECISION, value);
2031 if value_rug == value {
2032 Ok(Self(value_rug))
2033 } else {
2034 Err(TryFromf64Errors::NonRepresentableExactly {
2035 value,
2036 precision: PRECISION,
2037 backtrace: Backtrace::force_capture(),
2038 })
2039 }
2040 }
2041 Err(e) => Err(TryFromf64Errors::ValidationError { source: e }),
2042 }
2043 }
2044
2045 #[inline(always)]
2062 fn trunc_(self) -> Self {
2063 Self(self.0.trunc())
2064 }
2065
2066 #[inline(always)]
2068 fn two_() -> Self {
2069 Self(rug::Float::with_val(PRECISION, 2.))
2070 }
2071}
2072
2073#[cfg(feature = "rug")]
2075impl<const PRECISION: u32> Mul<ComplexRug<PRECISION>> for RealRug<PRECISION> {
2076 type Output = ComplexRug<PRECISION>;
2077
2078 #[inline(always)]
2079 fn mul(self, other: ComplexRug<PRECISION>) -> Self::Output {
2080 ComplexRug(self.0 * other.0)
2081 }
2082}
2083
2084#[cfg(feature = "rug")]
2086impl<const PRECISION: u32> MulComplexRight<Rug<PRECISION>> for RealRug<PRECISION> {}
2087
2088#[cfg(feature = "rug")]
2090impl<const PRECISION: u32> FunctionsGeneralType<Rug<PRECISION>> for ComplexRug<PRECISION> {}
2091
2092#[cfg(feature = "rug")]
2094impl<const PRECISION: u32> FunctionsComplexType<Rug<PRECISION>> for ComplexRug<PRECISION> {
2095 #[inline(always)]
2097 fn arg_(self) -> RealRug<PRECISION> {
2098 RealRug(self.0.arg().real().clone())
2099 }
2100
2101 #[inline(always)]
2108 fn new_(real_part: RealRug<PRECISION>, imag_part: RealRug<PRECISION>) -> Self {
2109 debug_assert!(
2110 real_part.0.is_finite(),
2111 "The real part is not finite (i.e. is infinite or NaN)."
2112 );
2113 debug_assert!(
2114 imag_part.0.is_finite(),
2115 "The imaginary part is not finite (i.e. is infinite or NaN)."
2116 );
2117
2118 Self(rug::Complex::with_val(
2119 PRECISION,
2120 (real_part.0, imag_part.0),
2121 ))
2122 }
2123
2124 #[inline(always)]
2126 fn real_(&self) -> RealRug<PRECISION> {
2127 RealRug(self.0.real().clone())
2128 }
2129
2130 #[inline(always)]
2132 fn imag_(&self) -> RealRug<PRECISION> {
2133 RealRug(self.0.imag().clone())
2134 }
2135
2136 #[inline(always)]
2142 fn set_real_(&mut self, real_part: RealRug<PRECISION>) {
2143 debug_assert!(
2144 real_part.0.is_finite(),
2145 "The real part is not finite (i.e. is infinite or NaN)."
2146 );
2147
2148 *self.0.mut_real() = real_part.0;
2149 }
2150
2151 #[inline(always)]
2157 fn set_imag_(&mut self, imag_part: RealRug<PRECISION>) {
2158 debug_assert!(
2159 imag_part.0.is_finite(),
2160 "The imaginary part is not finite (i.e. is infinite or NaN)."
2161 );
2162 *self.0.mut_imag() = imag_part.0;
2165 }
2166
2167 #[inline(always)]
2169 fn add_real_(&mut self, c: &RealRug<PRECISION>) {
2170 *self.0.mut_real() += c.as_ref();
2171
2172 debug_assert!(
2173 self.0.real().is_finite(),
2174 "The real part is not finite (i.e. is infinite or NaN)."
2175 );
2176 }
2177
2178 #[inline(always)]
2180 fn add_imag_(&mut self, c: &RealRug<PRECISION>) {
2181 *self.0.mut_imag() += c.as_ref();
2182
2183 debug_assert!(
2184 self.0.imag().is_finite(),
2185 "The imaginary part is not finite (i.e. is infinite or NaN)."
2186 );
2187 }
2188
2189 #[inline(always)]
2191 fn multiply_real_(&mut self, c: &RealRug<PRECISION>) {
2192 *self.0.mut_real() *= c.as_ref();
2193
2194 debug_assert!(
2195 self.0.real().is_finite(),
2196 "The real part is not finite (i.e. is infinite or NaN)."
2197 );
2198 }
2199
2200 #[inline(always)]
2202 fn multiply_imag_(&mut self, c: &RealRug<PRECISION>) {
2203 *self.0.mut_imag() *= c.as_ref();
2204
2205 debug_assert!(
2206 self.0.imag().is_finite(),
2207 "The imaginary part is not finite (i.e. is infinite or NaN)."
2208 );
2209 }
2210
2211 #[inline(always)]
2213 fn conj_(self) -> Self {
2214 Self(self.0.conj())
2215 }
2216
2217 #[inline(always)]
2221 fn try_from_f64_(real_part: f64, imag_part: f64) -> Result<Self, TryFromf64Errors> {
2222 let real_part = RealRug::<PRECISION>::try_from_f64_(real_part)?;
2223 let imag_part = RealRug::<PRECISION>::try_from_f64_(imag_part)?;
2224
2225 Ok(Self(rug::Complex::with_val(
2226 PRECISION,
2227 (real_part.0, imag_part.0),
2228 )))
2229 }
2230}
2231
2232#[cfg(feature = "rug")]
2234impl<const PRECISION: u32> MulComplexLeft<Rug<PRECISION>> for ComplexRug<PRECISION> {}
2235#[cfg(feature = "rug")]
2240impl<const PRECISION: u32> Mul<ComplexRug<PRECISION>> for &RealRug<PRECISION> {
2241 type Output = ComplexRug<PRECISION>;
2242
2243 fn mul(self, rhs: ComplexRug<PRECISION>) -> ComplexRug<PRECISION> {
2244 ComplexRug(rhs.0.mul(&self.0))
2245 }
2246}
2247#[inline(always)]
2284pub fn vec_f64_into_vec_float<T: NumKernel>(vec: Vec<f64>) -> Vec<T::RealType> {
2285 vec.into_iter()
2286 .map(|v| T::RealType::try_from_f64_(v).unwrap())
2287 .collect()
2288}
2289#[cfg(test)]
2293mod tests {
2294 use super::*;
2295 use core::ops::{Add, Div, Mul, Sub};
2296
2297 fn test_add_real<T>()
2298 where
2299 T: NumKernel,
2300 for<'a> &'a T::RealType: Add<T::RealType, Output = T::RealType>,
2301 {
2302 let a = T::RealType::one();
2303 let b = T::RealType::try_from_f64_(2.).unwrap();
2304
2305 let c_expected = T::RealType::try_from_f64_(3.0).unwrap();
2306
2307 let c = a.clone() + &b;
2308 assert_eq!(c, c_expected);
2309
2310 let c = &a + b.clone();
2311 assert_eq!(c, c_expected);
2312
2313 let c = a.clone() + b.clone();
2314 assert_eq!(c, c_expected);
2315 }
2316
2317 fn test_add_complex<T>()
2318 where
2319 T: NumKernel,
2320 for<'a> &'a T::ComplexType: Add<T::ComplexType, Output = T::ComplexType>,
2321 {
2322 let a = T::ComplexType::try_from_f64_(1., 2.).unwrap();
2323 let b = T::ComplexType::try_from_f64_(3., 4.).unwrap();
2324
2325 let c_expected = T::ComplexType::try_from_f64_(4., 6.).unwrap();
2326
2327 let c = a.clone() + &b;
2328 assert_eq!(c, c_expected);
2329
2330 let c = &a + b.clone();
2331 assert_eq!(c, c_expected);
2332
2333 let c = a.clone() + b.clone();
2334 assert_eq!(c, c_expected);
2335 }
2336
2337 fn test_sub_real<T>()
2338 where
2339 T: NumKernel,
2340 for<'a> &'a T::RealType: Sub<T::RealType, Output = T::RealType>,
2341 {
2342 let a = T::RealType::one();
2343 let b = T::RealType::try_from_f64_(2.).unwrap();
2344
2345 let c_expected = T::RealType::try_from_f64_(-1.0).unwrap();
2346
2347 let c = a.clone() - &b;
2348 assert_eq!(c, c_expected);
2349
2350 let c = &a - b.clone();
2351 assert_eq!(c, c_expected);
2352
2353 let c = a.clone() - b.clone();
2354 assert_eq!(c, c_expected);
2355 }
2356
2357 fn test_sub_complex<T>()
2358 where
2359 T: NumKernel,
2360 for<'a> &'a T::ComplexType: Sub<T::ComplexType, Output = T::ComplexType>,
2361 {
2362 let a = T::ComplexType::try_from_f64_(3., 2.).unwrap();
2363 let b = T::ComplexType::try_from_f64_(1., 4.).unwrap();
2364
2365 let c_expected = T::ComplexType::try_from_f64_(2., -2.).unwrap();
2366
2367 let c = a.clone() - &b;
2368 assert_eq!(c, c_expected);
2369
2370 let c = &a - b.clone();
2371 assert_eq!(c, c_expected);
2372
2373 let c = a.clone() - b.clone();
2374 assert_eq!(c, c_expected);
2375 }
2376
2377 fn test_mul_real<T>()
2378 where
2379 T: NumKernel,
2380 for<'a> &'a T::RealType: Mul<T::RealType, Output = T::RealType>,
2381 {
2382 let a = T::RealType::try_from_f64_(2.).unwrap();
2383 let b = T::RealType::try_from_f64_(3.).unwrap();
2384
2385 let c_expected = T::RealType::try_from_f64_(6.0).unwrap();
2386
2387 let c = a.clone() * &b;
2388 assert_eq!(c, c_expected);
2389
2390 let c = &a * b.clone();
2391 assert_eq!(c, c_expected);
2392
2393 let c = a.clone() * b.clone();
2394 assert_eq!(c, c_expected);
2395 }
2396
2397 fn test_mul_complex<T>()
2398 where
2399 T: NumKernel,
2400 for<'a> &'a T::ComplexType: Mul<T::ComplexType, Output = T::ComplexType>,
2401 {
2402 let a = T::ComplexType::try_from_f64_(3., 2.).unwrap();
2403 let b = T::ComplexType::try_from_f64_(1., 4.).unwrap();
2404
2405 let c_expected = T::ComplexType::try_from_f64_(-5., 14.).unwrap();
2406
2407 let c = a.clone() * &b;
2408 assert_eq!(c, c_expected);
2409
2410 let c = &a * b.clone();
2411 assert_eq!(c, c_expected);
2412
2413 let c = a.clone() * b.clone();
2414 assert_eq!(c, c_expected);
2415 }
2416
2417 fn test_div_real<T>()
2418 where
2419 T: NumKernel,
2420 for<'a> &'a T::RealType: Div<T::RealType, Output = T::RealType>,
2421 {
2422 let a = T::RealType::try_from_f64_(6.).unwrap();
2423 let b = T::RealType::try_from_f64_(2.).unwrap();
2424
2425 let c_expected = T::RealType::try_from_f64_(3.0).unwrap();
2426
2427 let c = a.clone() / &b;
2428 assert_eq!(c, c_expected);
2429
2430 let c = &a / b.clone();
2431 assert_eq!(c, c_expected);
2432
2433 let c = a.clone() / b.clone();
2434 assert_eq!(c, c_expected);
2435 }
2436
2437 fn test_div_complex<T>()
2438 where
2439 T: NumKernel,
2440 for<'a> &'a T::ComplexType: Div<T::ComplexType, Output = T::ComplexType>,
2441 {
2442 let a = T::ComplexType::try_from_f64_(-5., 14.).unwrap();
2443 let b = T::ComplexType::try_from_f64_(1., 4.).unwrap();
2444
2445 let c_expected = T::ComplexType::try_from_f64_(3., 2.).unwrap();
2446
2447 let c = a.clone() / &b;
2448 assert_eq!(c, c_expected);
2449
2450 let c = &a / b.clone();
2451 assert_eq!(c, c_expected);
2452
2453 let c = a.clone() / b.clone();
2454 assert_eq!(c, c_expected);
2455 }
2456
2457 fn test_neg_assign_real<T: NumKernel>() {
2458 let mut a = T::RealType::try_from_f64_(1.).unwrap();
2459 a.neg_assign();
2460
2461 let a_expected = T::RealType::try_from_f64_(-1.).unwrap();
2462 assert_eq!(a, a_expected);
2463 }
2464
2465 fn test_neg_assign_complex<T: NumKernel>() {
2466 let mut a = T::ComplexType::try_from_f64_(1., 2.).unwrap();
2467 a.neg_assign();
2468
2469 let a_expected = T::ComplexType::try_from_f64_(-1., -2.).unwrap();
2470 assert_eq!(a, a_expected);
2471 }
2472
2473 fn test_add_assign_real<T: NumKernel>() {
2474 let mut a = T::RealType::try_from_f64_(1.0).unwrap();
2475 let b = T::RealType::try_from_f64_(2.0).unwrap();
2476
2477 a += &b;
2478 let a_expected = T::RealType::try_from_f64_(3.0).unwrap();
2479 assert_eq!(a, a_expected);
2480
2481 a += b;
2482 let a_expected = T::RealType::try_from_f64_(5.0).unwrap();
2483 assert_eq!(a, a_expected);
2484 }
2485
2486 fn test_add_assign_complex<T: NumKernel>() {
2487 let mut a = T::ComplexType::try_from_f64_(1., 2.).unwrap();
2488 let b = T::ComplexType::try_from_f64_(3., 4.).unwrap();
2489
2490 a += &b;
2491 let a_expected = T::ComplexType::try_from_f64_(4., 6.).unwrap();
2492 assert_eq!(a, a_expected);
2493
2494 a += b;
2495 let a_expected = T::ComplexType::try_from_f64_(7., 10.).unwrap();
2496 assert_eq!(a, a_expected);
2497 }
2498
2499 fn test_sub_assign_real<T: NumKernel>() {
2500 let mut a = T::RealType::try_from_f64_(1.0).unwrap();
2501 let b = T::RealType::try_from_f64_(2.0).unwrap();
2502
2503 a -= &b;
2504 let a_expected = T::RealType::try_from_f64_(-1.0).unwrap();
2505 assert_eq!(a, a_expected);
2506
2507 a -= b;
2508 let a_expected = T::RealType::try_from_f64_(-3.0).unwrap();
2509 assert_eq!(a, a_expected);
2510 }
2511
2512 fn test_sub_assign_complex<T: NumKernel>() {
2513 let mut a = T::ComplexType::try_from_f64_(3., 2.).unwrap();
2514 let b = T::ComplexType::try_from_f64_(2., 4.).unwrap();
2515
2516 a -= &b;
2517 let a_expected = T::ComplexType::try_from_f64_(1., -2.).unwrap();
2518 assert_eq!(a, a_expected);
2519
2520 a -= b;
2521 let a_expected = T::ComplexType::try_from_f64_(-1., -6.).unwrap();
2522 assert_eq!(a, a_expected);
2523 }
2524
2525 fn test_mul_assign_real<T: NumKernel>() {
2526 let mut a = T::RealType::try_from_f64_(1.0).unwrap();
2527 let b = T::RealType::try_from_f64_(2.0).unwrap();
2528
2529 a *= &b;
2530 let a_expected = T::RealType::try_from_f64_(2.0).unwrap();
2531 assert_eq!(a, a_expected);
2532
2533 a *= b;
2534 let a_expected = T::RealType::try_from_f64_(4.0).unwrap();
2535 assert_eq!(a, a_expected);
2536 }
2537
2538 fn test_mul_assign_complex<T: NumKernel>() {
2539 let mut a = T::ComplexType::try_from_f64_(3., 2.).unwrap();
2540 let b = T::ComplexType::try_from_f64_(2., 4.).unwrap();
2541
2542 a *= &b;
2543 let a_expected = T::ComplexType::try_from_f64_(-2., 16.).unwrap();
2544 assert_eq!(a, a_expected);
2545
2546 a *= b;
2547 let a_expected = T::ComplexType::try_from_f64_(-68., 24.).unwrap();
2548 assert_eq!(a, a_expected);
2549 }
2550
2551 fn test_div_assign_real<T: NumKernel>() {
2552 let mut a = T::RealType::try_from_f64_(4.0).unwrap();
2553 let b = T::RealType::try_from_f64_(2.0).unwrap();
2554
2555 a /= &b;
2556 let a_expected = T::RealType::try_from_f64_(2.0).unwrap();
2557 assert_eq!(a, a_expected);
2558
2559 a /= b;
2560 let a_expected = T::RealType::try_from_f64_(1.0).unwrap();
2561 assert_eq!(a, a_expected);
2562 }
2563
2564 fn test_div_assign_complex<T: NumKernel>() {
2565 let mut a = T::ComplexType::try_from_f64_(-68., 24.).unwrap();
2566 let b = T::ComplexType::try_from_f64_(2., 4.).unwrap();
2567
2568 a /= &b;
2569 let a_expected = T::ComplexType::try_from_f64_(-2., 16.).unwrap();
2570 assert_eq!(a, a_expected);
2571
2572 a /= b;
2573 let a_expected = T::ComplexType::try_from_f64_(3., 2.).unwrap();
2574 assert_eq!(a, a_expected);
2575 }
2576
2577 fn test_abs_real<T: NumKernel>() {
2578 let a = T::RealType::try_from_f64_(-1.).unwrap();
2579
2580 let abs = a.abs();
2581 let expected = T::RealType::try_from_f64_(1.).unwrap();
2582 assert_eq!(abs, expected);
2583 }
2584
2585 fn test_abs_complex<T: NumKernel>() {
2586 let a = T::ComplexType::try_from_f64_(-3., 4.).unwrap();
2587
2588 let abs = a.abs();
2589 let expected = T::RealType::try_from_f64_(5.).unwrap();
2590 assert_eq!(abs, expected);
2591 }
2592
2593 fn test_mul_add_real<T: NumKernel>() {
2594 let a = T::RealType::try_from_f64_(2.0).unwrap();
2595 let b = T::RealType::try_from_f64_(3.0).unwrap();
2596 let c = T::RealType::try_from_f64_(1.0).unwrap();
2597
2598 let d_expected = T::RealType::try_from_f64_(7.0).unwrap();
2599
2600 let d = a.mul_add(&b, &c);
2601 assert_eq!(d, d_expected);
2602 }
2603
2604 fn test_mul_add_complex<T: NumKernel>() {
2605 let a = T::ComplexType::try_from_f64_(2., -3.).unwrap();
2606 let b = T::ComplexType::try_from_f64_(3., 1.).unwrap();
2607 let c = T::ComplexType::try_from_f64_(1., -4.).unwrap();
2608
2609 let d_expected = T::ComplexType::try_from_f64_(10., -11.).unwrap();
2610
2611 let d = a.mul_add(&b, &c);
2612 assert_eq!(d, d_expected);
2613 }
2614
2615 fn test_mul_complex_with_real<T>()
2677 where
2678 T: NumKernel,
2679 for<'a> &'a T::RealType: Mul<T::ComplexType, Output = T::ComplexType>,
2680 {
2681 let a = T::ComplexType::try_from_f64_(1., 2.).unwrap();
2682 let b = T::RealType::try_from_f64_(3.).unwrap();
2683
2684 let a_times_b_expected = T::ComplexType::try_from_f64_(3., 6.).unwrap();
2685 let b_times_a_expected = a_times_b_expected.clone();
2686
2687 let a_times_b = a.clone() * &b;
2688 assert_eq!(a_times_b, a_times_b_expected);
2689
2690 let a_times_b = a.clone() * b.clone();
2694 assert_eq!(a_times_b, a_times_b_expected);
2695
2696 let b_times_a = &b * a.clone();
2700 assert_eq!(b_times_a, b_times_a_expected);
2701
2702 let b_times_a = b.clone() * a.clone();
2703 assert_eq!(b_times_a, b_times_a_expected);
2704 }
2705
2706 fn test_mul_assign_complex_with_real<T>()
2707 where
2708 T: NumKernel,
2709 {
2710 let a = T::ComplexType::try_from_f64_(1., 2.).unwrap();
2711 let b = T::RealType::try_from_f64_(3.).unwrap();
2712
2713 let a_times_b_expected = T::ComplexType::try_from_f64_(3., 6.).unwrap();
2714
2715 let mut a_times_b = a.clone();
2716 a_times_b *= &b;
2717 assert_eq!(a_times_b, a_times_b_expected);
2718
2719 let mut a_times_b = a.clone();
2720 a_times_b *= b;
2721 assert_eq!(a_times_b, a_times_b_expected);
2722 }
2723
2724 mod native64 {
2725 use super::*;
2726
2727 mod real {
2728 use super::*;
2729
2730 #[test]
2731 fn from_f64() {
2732 let v_native64 =
2733 <f64 as FunctionsRealType<Native64>>::try_from_f64_(16.25).unwrap();
2734 assert_eq!(v_native64, 16.25);
2735 }
2736
2737 #[test]
2738 fn zero() {
2739 test_zero::<Native64>();
2740 }
2741
2742 #[test]
2743 fn one() {
2744 test_one::<Native64>();
2745 }
2746
2747 #[test]
2748 fn add() {
2749 test_add_real::<Native64>();
2750 }
2751
2752 #[test]
2753 fn sub() {
2754 test_sub_real::<Native64>();
2755 }
2756
2757 #[test]
2758 fn mul() {
2759 test_mul_real::<Native64>();
2760 }
2761
2762 #[test]
2763 fn div() {
2764 test_div_real::<Native64>();
2765 }
2766
2767 #[test]
2768 fn neg_assign() {
2769 test_neg_assign_real::<Native64>();
2770 }
2771
2772 #[test]
2773 fn add_assign() {
2774 test_add_assign_real::<Native64>();
2775 }
2776
2777 #[test]
2778 fn sub_assign() {
2779 test_sub_assign_real::<Native64>();
2780 }
2781
2782 #[test]
2783 fn mul_assign() {
2784 test_mul_assign_real::<Native64>();
2785 }
2786
2787 #[test]
2788 fn div_assign() {
2789 test_div_assign_real::<Native64>();
2790 }
2791
2792 #[test]
2793 fn abs() {
2794 test_abs_real::<Native64>();
2795 }
2796
2797 #[test]
2798 fn mul_add() {
2799 test_mul_add_real::<Native64>();
2800 }
2801
2802 #[test]
2803 fn recip() {
2804 test_recip::<Native64>();
2805 }
2806
2807 #[test]
2808 fn acos() {
2809 let a = 0.;
2810
2811 let pi_over_2 = a.acos_();
2812 let expected = 1.5707963267948966;
2813 assert_eq!(pi_over_2, expected);
2814 }
2815
2816 #[test]
2817 fn asin() {
2818 let a = 1.;
2819
2820 let pi_over_2 = a.asin_();
2821 let expected = 1.5707963267948966;
2822 assert_eq!(pi_over_2, expected);
2823 }
2824
2825 #[test]
2826 fn cos() {
2827 test_cos::<Native64>();
2828 }
2829
2830 #[test]
2831 fn sin() {
2832 test_sin::<Native64>();
2833 }
2834 }
2835
2836 mod complex {
2837 use super::*;
2838 use num::Complex;
2839
2840 #[test]
2841 fn from_f64() {
2842 let v = <Complex<f64> as FunctionsComplexType<Native64>>::try_from_f64_(16.25, 2.)
2843 .unwrap();
2844 assert_eq!(v.real_(), 16.25);
2845 assert_eq!(v.imag_(), 2.);
2846 }
2847
2848 #[test]
2849 fn conj() {
2850 let v = <Complex<f64> as FunctionsComplexType<Native64>>::try_from_f64_(16.25, 2.)
2851 .unwrap();
2852
2853 let v_conj = v.conj_();
2854 assert_eq!(v_conj.real_(), 16.25);
2855 assert_eq!(v_conj.imag_(), -2.);
2856 }
2857
2858 #[test]
2859 fn add() {
2860 test_add_complex::<Native64>();
2861 }
2862
2863 #[test]
2864 fn sub() {
2865 test_sub_complex::<Native64>();
2866 }
2867
2868 #[test]
2869 fn mul() {
2870 test_mul_complex::<Native64>();
2871 }
2872
2873 #[test]
2874 fn div() {
2875 test_div_complex::<Native64>();
2876 }
2877
2878 #[test]
2879 fn neg_assign() {
2880 test_neg_assign_complex::<Native64>();
2881 }
2882
2883 #[test]
2884 fn add_assign() {
2885 test_add_assign_complex::<Native64>();
2886 }
2887
2888 #[test]
2889 fn sub_assign() {
2890 test_sub_assign_complex::<Native64>();
2891 }
2892
2893 #[test]
2894 fn mul_assign() {
2895 test_mul_assign_complex::<Native64>();
2896 }
2897
2898 #[test]
2899 fn div_assign() {
2900 test_div_assign_complex::<Native64>();
2901 }
2902
2903 #[test]
2904 fn abs() {
2905 test_abs_complex::<Native64>();
2906 }
2907
2908 #[test]
2909 fn mul_add() {
2910 test_mul_add_complex::<Native64>();
2911 }
2912
2913 #[test]
2926 fn mul_complex_with_real() {
2927 test_mul_complex_with_real::<Native64>();
2928 }
2929
2930 #[test]
2931 fn mul_assign_complex_with_real() {
2932 test_mul_assign_complex_with_real::<Native64>();
2933 }
2934 }
2935 }
2936
2937 #[cfg(feature = "rug")]
2939 mod rug_ {
2940 use super::*;
2941
2942 mod real {
2943 use super::*;
2944
2945 #[test]
2946 fn from_f64() {
2947 let v_100bits = RealRug::<100>::try_from_f64_(16.25).unwrap();
2948
2949 assert_eq!(v_100bits, 16.25);
2950
2951 let v_53bits = RealRug::<53>::try_from_f64_(16.25).unwrap();
2952 assert_eq!(v_53bits, 16.25);
2953
2954 let v_7bits = RealRug::<7>::try_from_f64_(16.25).unwrap();
2956 assert_eq!(v_7bits, 16.25);
2957 }
2958
2959 #[test]
2960 #[should_panic]
2961 fn from_f64_failing() {
2962 let _v_6bits = RealRug::<6>::try_from_f64_(16.25).unwrap();
2964 }
2965
2966 #[test]
2967 fn zero() {
2968 test_zero::<Rug<64>>();
2969 test_zero::<Rug<100>>();
2970 }
2971
2972 #[test]
2973 fn one() {
2974 test_one::<Rug<64>>();
2975 test_one::<Rug<100>>();
2976 }
2977
2978 #[test]
2979 fn add() {
2980 test_add_real::<Rug<100>>();
2981 }
2982
2983 #[test]
2984 fn sub() {
2985 test_sub_real::<Rug<100>>();
2986 }
2987
2988 #[test]
2989 fn mul() {
2990 test_mul_real::<Rug<100>>();
2991 }
2992
2993 #[test]
2994 fn div() {
2995 test_div_real::<Rug<100>>();
2996 }
2997
2998 #[test]
2999 fn neg_assign() {
3000 test_neg_assign_real::<Rug<100>>();
3001 }
3002
3003 #[test]
3004 fn add_assign() {
3005 test_add_assign_real::<Rug<100>>();
3006 }
3007
3008 #[test]
3009 fn sub_assign() {
3010 test_sub_assign_real::<Rug<100>>();
3011 }
3012
3013 #[test]
3014 fn mul_assign() {
3015 test_mul_assign_real::<Rug<100>>();
3016 }
3017
3018 #[test]
3019 fn div_assign() {
3020 test_div_assign_real::<Rug<100>>();
3021 }
3022
3023 #[test]
3024 fn abs() {
3025 test_abs_real::<Rug<100>>();
3026 }
3027
3028 #[test]
3029 fn mul_add() {
3030 test_mul_add_real::<Rug<100>>();
3031 }
3032
3033 #[test]
3034 fn recip() {
3035 test_recip::<Rug<64>>();
3036 test_recip::<Rug<100>>();
3037 }
3038
3039 #[test]
3040 fn acos() {
3041 {
3042 let a = RealRug::<53>::zero();
3043 let pi_over_2 = RealRug::<53>::acos_(a);
3044 let expected = rug::Float::with_val(53, 1.5707963267948966);
3045 assert_eq!(pi_over_2.as_ref(), &expected);
3046 }
3047 {
3048 let a = RealRug::<100>::zero();
3049 let pi_over_2 = RealRug::<100>::acos_(a);
3050 let expected = rug::Float::with_val(
3051 100,
3052 rug::Float::parse("1.5707963267948966192313216916397e0").unwrap(),
3053 );
3054 assert_eq!(pi_over_2.as_ref(), &expected);
3055 }
3056 }
3057
3058 #[test]
3059 fn asin() {
3060 {
3061 let a = RealRug::<53>::one();
3062 let pi_over_2 = RealRug::<53>::asin_(a);
3063 let expected = rug::Float::with_val(53, 1.5707963267948966);
3064 assert_eq!(pi_over_2.as_ref(), &expected);
3065 }
3066 {
3067 let a = RealRug::<100>::one();
3068 let pi_over_2 = RealRug::<100>::asin_(a);
3069 let expected = rug::Float::with_val(
3070 100,
3071 rug::Float::parse("1.5707963267948966192313216916397e0").unwrap(),
3072 );
3073 assert_eq!(pi_over_2.as_ref(), &expected);
3074 }
3075 }
3076
3077 #[test]
3078 fn cos() {
3079 test_cos::<Rug<64>>();
3080 test_cos::<Rug<100>>();
3081 }
3082
3083 #[test]
3084 fn sin() {
3085 test_sin::<Rug<64>>();
3086 test_sin::<Rug<100>>();
3087 }
3088
3089 #[test]
3090 fn dot_product() {
3091 let a = &[
3092 RealRug::<100>::try_from_f64_(1.).unwrap(),
3093 RealRug::<100>::try_from_f64_(2.).unwrap(),
3094 ];
3095
3096 let b = &[
3097 RealRug::<100>::try_from_f64_(2.).unwrap(),
3098 RealRug::<100>::try_from_f64_(-1.).unwrap(),
3099 ];
3100
3101 let a: Vec<_> = a.iter().map(|a_i| a_i.as_ref()).collect();
3102 let b: Vec<_> = b.iter().map(|b_i| b_i.as_ref()).collect();
3103
3104 let value =
3105 RealRug::<100>(rug::Float::dot(a.into_iter().zip(b.into_iter())).complete(100));
3106
3107 assert_eq!(value.as_ref(), &rug::Float::with_val(100, 0.));
3108 }
3109 }
3110
3111 mod complex {
3112 use super::*;
3113
3114 #[test]
3115 fn from_f64() {
3116 let v_100bits = ComplexRug::<100>::try_from_f64_(16.25, 2.).unwrap();
3117 assert_eq!(ComplexRug::<100>::real_(&v_100bits), 16.25);
3118 assert_eq!(ComplexRug::<100>::imag_(&v_100bits), 2.);
3119
3120 let v_53bits = ComplexRug::<53>::try_from_f64_(16.25, 2.).unwrap();
3121 assert_eq!(ComplexRug::<53>::real_(&v_53bits), 16.25);
3122 assert_eq!(ComplexRug::<53>::imag_(&v_53bits), 2.);
3123
3124 let v_7bits = ComplexRug::<7>::try_from_f64_(16.25, 2.).unwrap();
3126 assert_eq!(ComplexRug::<7>::real_(&v_7bits), 16.25);
3127 assert_eq!(ComplexRug::<7>::imag_(&v_7bits), 2.);
3128 }
3129
3130 #[test]
3131 #[should_panic]
3132 fn from_f64_failing() {
3133 let _v_6bits = ComplexRug::<6>::try_from_f64_(16.25, 2.).unwrap();
3135 }
3136
3137 #[test]
3138 fn conj() {
3139 let v = ComplexRug::<100>::try_from_f64_(16.25, 2.).unwrap();
3140
3141 let v_conj = ComplexRug::<100>::conj_(v);
3142 assert_eq!(ComplexRug::<100>::real_(&v_conj), 16.25);
3143 assert_eq!(ComplexRug::<100>::imag_(&v_conj), -2.);
3144 }
3145
3146 #[test]
3147 fn add() {
3148 test_add_complex::<Rug<100>>();
3149 }
3150
3151 #[test]
3152 fn sub() {
3153 test_sub_complex::<Rug<100>>();
3154 }
3155
3156 #[test]
3157 fn mul() {
3158 test_mul_complex::<Rug<100>>();
3159 }
3160
3161 #[test]
3162 fn div() {
3163 test_div_complex::<Rug<100>>();
3164 }
3165
3166 #[test]
3167 fn neg_assign() {
3168 test_neg_assign_complex::<Rug<100>>();
3169 }
3170
3171 #[test]
3172 fn add_assign() {
3173 test_add_assign_complex::<Rug<100>>();
3174 }
3175
3176 #[test]
3177 fn sub_assign() {
3178 test_sub_assign_complex::<Rug<100>>();
3179 }
3180
3181 #[test]
3182 fn mul_assign() {
3183 test_mul_assign_complex::<Rug<100>>();
3184 }
3185
3186 #[test]
3187 fn div_assign() {
3188 test_div_assign_complex::<Rug<100>>();
3189 }
3190
3191 #[test]
3192 fn abs() {
3193 test_abs_complex::<Rug<100>>();
3194 }
3195
3196 #[test]
3197 fn mul_add() {
3198 test_mul_add_complex::<Rug<100>>();
3199 }
3200 #[test]
3212 fn mul_complex_with_real() {
3213 test_mul_complex_with_real::<Rug<100>>();
3214 }
3215
3216 #[test]
3217 fn mul_assign_complex_with_real() {
3218 test_mul_assign_complex_with_real::<Rug<100>>();
3219 }
3220
3221 #[test]
3222 fn dot_product() {
3223 let a = &[
3224 ComplexRug::<100>::try_from_f64_(1., 3.).unwrap(),
3225 ComplexRug::<100>::try_from_f64_(2., 4.).unwrap(),
3226 ];
3227
3228 let b = &[
3229 ComplexRug::<100>::try_from_f64_(-2., -5.).unwrap(),
3230 ComplexRug::<100>::try_from_f64_(-1., 6.).unwrap(),
3231 ];
3232
3233 let a: Vec<_> = a.iter().map(|a_i| a_i.as_ref()).collect();
3234 let b: Vec<_> = b.iter().map(|b_i| b_i.as_ref()).collect();
3235
3236 let a_times_a = ComplexRug::<100>(
3238 rug::Complex::dot(a.clone().into_iter().zip(a.clone().into_iter()))
3239 .complete((100, 100)),
3240 );
3241 assert_eq!(
3242 a_times_a.as_ref(),
3243 &rug::Complex::with_val(100, (-20., 22.))
3244 );
3245
3246 let a_times_b = ComplexRug::<100>(
3248 rug::Complex::dot(a.clone().into_iter().zip(b.clone().into_iter()))
3249 .complete((100, 100)),
3250 );
3251 assert_eq!(
3252 a_times_b.as_ref(),
3253 &rug::Complex::with_val(100, (-13., -3.))
3254 );
3255
3256 let b_times_a = ComplexRug::<100>(
3258 rug::Complex::dot(b.into_iter().zip(a.into_iter())).complete((100, 100)),
3259 );
3260 assert_eq!(
3261 b_times_a.as_ref(),
3262 &rug::Complex::with_val(100, (-13., -3.))
3263 );
3264 }
3265 }
3266 }
3267
3268 fn test_sin<T: NumKernel>() {
3269 let a = T::RealType::zero();
3270
3271 let a = a.sin_();
3272 let expected = T::RealType::zero();
3273 assert_eq!(a, expected);
3274 }
3275
3276 fn test_cos<T: NumKernel>() {
3277 let a = T::RealType::zero();
3278
3279 let a = a.cos_();
3280 let expected = T::RealType::one();
3281 assert_eq!(a, expected);
3282 }
3283
3284 fn test_recip<T: NumKernel>() {
3285 let a = T::RealType::two_();
3286
3287 let a = a.try_reciprocal().unwrap();
3288 let expected = T::RealType::one_div_2_();
3289 assert_eq!(a, expected);
3290 }
3291
3292 fn test_zero<T: NumKernel>() {
3293 let a = T::RealType::zero();
3294
3295 assert_eq!(a, 0.0);
3296 }
3297
3298 fn test_one<T: NumKernel>() {
3299 let a = T::RealType::one();
3300
3301 assert_eq!(a, 1.0);
3302 }
3303}
3304
3305#[cfg(test)]
3306mod tests_new {
3307 use super::*;
3308
3309 mod functions_general_type {
3310 use super::*;
3311
3312 mod native64 {
3313 use super::*;
3314
3315 mod real {
3316 use super::*;
3317
3318 #[test]
3319 fn test_acos_() {
3320 let value: f64 = 0.5;
3321 let result = value.acos_();
3322 assert_eq!(result, value.acos());
3323 }
3324
3325 #[test]
3326 fn test_acosh_() {
3327 let value: f64 = 1.5;
3328 let result = value.acosh_();
3329 assert_eq!(result, value.acosh());
3330 }
3331
3332 #[test]
3333 fn test_asin_() {
3334 let value: f64 = 0.5;
3335 let result = value.asin_();
3336 assert_eq!(result, value.asin());
3337 }
3338
3339 #[test]
3340 fn test_asinh_() {
3341 let value: f64 = 0.5;
3342 let result = value.asinh_();
3343 assert_eq!(result, value.asinh());
3344 }
3345
3346 #[test]
3347 fn test_atan_() {
3348 let value: f64 = 0.5;
3349 let result = value.atan_();
3350 assert_eq!(result, value.atan());
3351 }
3352
3353 #[test]
3354 fn test_atanh_() {
3355 let value: f64 = 0.5;
3356 let result = value.atanh_();
3357 assert_eq!(result, value.atanh());
3358 }
3359
3360 #[test]
3361 fn test_cos_() {
3362 let value: f64 = 0.5;
3363 let result = value.cos_();
3364 assert_eq!(result, value.cos());
3365 }
3366
3367 #[test]
3368 fn test_cosh_() {
3369 let value: f64 = 0.5;
3370 let result = value.cosh_();
3371 assert_eq!(result, value.cosh());
3372 }
3373
3374 #[test]
3375 fn test_exp_() {
3376 let value: f64 = 0.5;
3377 let result = value.exp_();
3378 print!("result = {:?}", result);
3379
3380 assert_eq!(result, value.exp());
3381 }
3382
3383 #[test]
3384 fn test_is_finite_() {
3385 let value: f64 = 0.5;
3386 assert!(value.is_finite_());
3387
3388 let value: f64 = f64::INFINITY;
3389 assert!(!value.is_finite_());
3390 }
3391
3392 #[test]
3393 fn test_is_infinite_() {
3394 let value: f64 = f64::INFINITY;
3395 assert!(value.is_infinite_());
3396
3397 let value: f64 = 0.5;
3398 assert!(!value.is_infinite_());
3399 }
3400
3401 #[test]
3402 fn test_ln_() {
3403 let value: f64 = 2.718281828459045;
3404 let result = value.ln_();
3405 println!("result = {:?}", result);
3406 assert_eq!(result, value.ln());
3407 }
3408
3409 #[test]
3410 fn test_log10_() {
3411 let value: f64 = 10.0;
3412 let result = value.log10_();
3413 println!("result = {:?}", result);
3414 assert_eq!(result, value.log10());
3415 }
3416
3417 #[test]
3418 fn test_log2_() {
3419 let value: f64 = 8.0;
3420 let result = value.log2_();
3421 println!("result = {:?}", result);
3422 assert_eq!(result, value.log2());
3423 }
3424
3425 #[test]
3426 fn test_recip_() {
3427 let value: f64 = 2.0;
3428 let result = value.try_reciprocal().unwrap();
3429 assert_eq!(result, value.recip());
3430 }
3431
3432 #[test]
3433 fn test_sin_() {
3434 let value: f64 = 0.5;
3435 let result = value.sin_();
3436 assert_eq!(result, value.sin());
3437 }
3438
3439 #[test]
3440 fn test_sinh_() {
3441 let value: f64 = 0.5;
3442 let result = value.sinh_();
3443 assert_eq!(result, value.sinh());
3444 }
3445
3446 #[test]
3447 fn sqrt() {
3448 let value: f64 = 4.0;
3449 let result = value.sqrt();
3450 assert_eq!(result, value.sqrt());
3451 }
3452
3453 #[test]
3454 fn try_sqrt() {
3455 let value: f64 = 4.0;
3456 let result = value.try_sqrt().unwrap();
3457 assert_eq!(result, value.sqrt());
3458
3459 assert!((-1.0).try_sqrt().is_err());
3460 }
3461
3462 #[test]
3463 fn test_tan_() {
3464 let value: f64 = 0.5;
3465 let result = value.tan_();
3466 assert_eq!(result, value.tan());
3467 }
3468
3469 #[test]
3470 fn test_tanh_() {
3471 let value: f64 = 0.5;
3472 let result = value.tanh_();
3473 assert_eq!(result, value.tanh());
3474 }
3475 }
3476
3477 mod complex {
3478 use super::*;
3479
3480 #[test]
3481 fn test_acos_() {
3482 let value: Complex<f64> = Complex::new(0.5, 0.5);
3483 let result = value.acos_();
3484 assert_eq!(result, value.acos());
3485 }
3486
3487 #[test]
3488 fn test_acosh_() {
3489 let value: Complex<f64> = Complex::new(1.5, 0.5);
3490 let result = value.acosh_();
3491 assert_eq!(result, value.acosh());
3492 }
3493
3494 #[test]
3495 fn test_asin_() {
3496 let value: Complex<f64> = Complex::new(0.5, 0.5);
3497 let result = value.asin_();
3498 assert_eq!(result, value.asin());
3499 }
3500
3501 #[test]
3502 fn test_asinh_() {
3503 let value: Complex<f64> = Complex::new(0.5, 0.5);
3504 let result = value.asinh_();
3505 assert_eq!(result, value.asinh());
3506 }
3507
3508 #[test]
3509 fn test_atan_() {
3510 let value: Complex<f64> = Complex::new(0.5, 0.5);
3511 let result = value.atan_();
3512 assert_eq!(result, value.atan());
3513 }
3514
3515 #[test]
3516 fn test_atanh_() {
3517 let value: Complex<f64> = Complex::new(0.5, 0.5);
3518 let result = value.atanh_();
3519 assert_eq!(result, value.atanh());
3520 }
3521
3522 #[test]
3523 fn test_cos_() {
3524 let value: Complex<f64> = Complex::new(0.5, 0.5);
3525 let result = value.cos_();
3526 assert_eq!(result, value.cos());
3527 }
3528
3529 #[test]
3530 fn test_cosh_() {
3531 let value: Complex<f64> = Complex::new(0.5, 0.5);
3532 let result = value.cosh_();
3533 assert_eq!(result, value.cosh());
3534 }
3535
3536 #[test]
3537 fn test_exp_() {
3538 let value: Complex<f64> = Complex::new(0.5, 0.5);
3539 let result = value.exp_();
3540 print!("result = {:?}", result);
3541 assert_eq!(result, value.exp());
3542 }
3543
3544 #[test]
3545 fn test_is_finite_() {
3546 let value: Complex<f64> = Complex::new(0.5, 0.5);
3547 assert!(value.is_finite_());
3548
3549 let value: Complex<f64> = Complex::new(f64::INFINITY, 0.5);
3550 assert!(!value.is_finite_());
3551 }
3552
3553 #[test]
3554 fn test_is_infinite_() {
3555 let value: Complex<f64> = Complex::new(f64::INFINITY, 0.5);
3556 assert!(value.is_infinite_());
3557
3558 let value: Complex<f64> = Complex::new(0.5, 0.5);
3559 assert!(!value.is_infinite_());
3560 }
3561
3562 #[test]
3563 fn test_ln_() {
3564 let value: Complex<f64> = Complex::new(2.718281828459045, 1.0);
3565 let result = value.ln_();
3566 println!("result = {:?}", result);
3567 assert_eq!(result, value.ln());
3568 }
3569
3570 #[test]
3571 fn test_log10_() {
3572 let value: Complex<f64> = Complex::new(10.0, 1.0);
3573 let result = value.log10_();
3574 println!("result = {:?}", result);
3575 assert_eq!(result, value.log10());
3576 }
3577
3578 #[test]
3579 fn test_log2_() {
3580 let value: Complex<f64> = Complex::new(8.0, 1.0);
3581 let result = value.log2_();
3582 println!("result = {:?}", result);
3583 assert_eq!(result, value.log2());
3584 }
3585
3586 #[test]
3587 fn test_recip_() {
3588 let value: Complex<f64> = Complex::new(2.0, 0.0);
3589 let result = value.try_reciprocal().unwrap();
3590 assert_eq!(result, value.finv());
3591 }
3592
3593 #[test]
3594 fn test_sin_() {
3595 let value: Complex<f64> = Complex::new(0.5, 0.5);
3596 let result = value.sin_();
3597 assert_eq!(result, value.sin());
3598 }
3599
3600 #[test]
3601 fn test_sinh_() {
3602 let value: Complex<f64> = Complex::new(0.5, 0.5);
3603 let result = value.sinh_();
3604 assert_eq!(result, value.sinh());
3605 }
3606
3607 #[test]
3608 fn sqrt() {
3609 let value: Complex<f64> = Complex::new(4.0, 1.0);
3610 let result = value.sqrt();
3611 assert_eq!(result, value.sqrt());
3612 }
3613
3614 #[test]
3615 fn try_sqrt() {
3616 let value: Complex<f64> = Complex::new(4.0, 1.0);
3617 let result = value.try_sqrt().unwrap();
3618 assert_eq!(result, value.sqrt());
3619 }
3620
3621 #[test]
3622 fn test_tan_() {
3623 let value: Complex<f64> = Complex::new(0.5, 0.5);
3624 let result = value.tan_();
3625 assert_eq!(result, value.tan());
3626 }
3627
3628 #[test]
3629 fn test_tanh_() {
3630 let value: Complex<f64> = Complex::new(0.5, 0.5);
3631 let result = value.tanh_();
3632 assert_eq!(result, value.tanh());
3633 }
3634 }
3635 }
3636
3637 #[cfg(feature = "rug")]
3638 mod rug100 {
3639 use super::*;
3640
3641 const PRECISION: u32 = 100;
3642
3643 mod real {
3644 use super::*;
3645 use rug::Float;
3646
3647 #[test]
3648 fn test_acos_() {
3649 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3650 let result = value.clone().acos_();
3651 assert_eq!(
3652 result,
3653 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.acos()))
3654 );
3655 }
3656
3657 #[test]
3658 fn test_acosh_() {
3659 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 1.5));
3660 let result = value.clone().acosh_();
3661 assert_eq!(
3662 result,
3663 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.acosh()))
3664 );
3665 }
3666
3667 #[test]
3668 fn test_asin_() {
3669 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3670 let result = value.clone().asin_();
3671 assert_eq!(
3672 result,
3673 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.asin()))
3674 );
3675 }
3676
3677 #[test]
3678 fn test_asinh_() {
3679 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3680 let result = value.clone().asinh_();
3681 assert_eq!(
3682 result,
3683 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.asinh()))
3684 );
3685 }
3686
3687 #[test]
3688 fn test_atan_() {
3689 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3690 let result = value.clone().atan_();
3691 assert_eq!(
3692 result,
3693 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.atan()))
3694 );
3695 }
3696
3697 #[test]
3698 fn test_atanh_() {
3699 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3700 let result = value.clone().atanh_();
3701 assert_eq!(
3702 result,
3703 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.atanh()))
3704 );
3705 }
3706
3707 #[test]
3708 fn test_cos_() {
3709 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3710 let result = value.clone().cos_();
3711 assert_eq!(
3712 result,
3713 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.cos()))
3714 );
3715 }
3716
3717 #[test]
3718 fn test_cosh_() {
3719 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3720 let result = value.clone().cosh_();
3721 assert_eq!(
3722 result,
3723 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.cosh()))
3724 );
3725 }
3726
3727 #[test]
3728 fn test_exp_() {
3729 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3730 let result = value.clone().exp_();
3731 print!("result = {:?}", result);
3732 assert_eq!(
3733 result,
3734 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.exp()))
3735 );
3736 }
3737
3738 #[test]
3739 fn test_is_finite_() {
3740 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3741 assert!(value.is_finite_());
3742
3743 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, f64::INFINITY));
3744 assert!(!value.is_finite_());
3745 }
3746
3747 #[test]
3748 fn test_is_infinite_() {
3749 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, f64::INFINITY));
3750 assert!(value.is_infinite_());
3751
3752 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3753 assert!(!value.is_infinite_());
3754 }
3755
3756 #[test]
3757 fn test_ln_() {
3758 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 2.718281828459045));
3759 let result = value.clone().ln_();
3760 println!("result = {:?}", result);
3761 assert_eq!(
3762 result,
3763 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.ln()))
3764 );
3765 }
3766
3767 #[test]
3768 fn test_log10_() {
3769 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 10.0));
3770 let result = value.clone().log10_();
3771 println!("result = {:?}", result);
3772 assert_eq!(
3773 result,
3774 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.log10()))
3775 );
3776 }
3777
3778 #[test]
3779 fn test_log2_() {
3780 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 8.0));
3781 let result = value.clone().log2_();
3782 println!("result = {:?}", result);
3783 assert_eq!(
3784 result,
3785 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.log2()))
3786 );
3787 }
3788
3789 #[test]
3790 fn test_recip_() {
3791 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 2.0));
3792 let result = value.clone().try_reciprocal().unwrap();
3793 assert_eq!(
3794 result,
3795 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.recip()))
3796 );
3797 }
3798
3799 #[test]
3800 fn test_sin_() {
3801 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3802 let result = value.clone().sin_();
3803 assert_eq!(
3804 result,
3805 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.sin()))
3806 );
3807 }
3808
3809 #[test]
3810 fn test_sinh_() {
3811 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3812 let result = value.clone().sinh_();
3813 assert_eq!(
3814 result,
3815 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.sinh()))
3816 );
3817 }
3818
3819 #[test]
3820 fn sqrt() {
3821 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
3822 let result = value.clone().sqrt();
3823 assert_eq!(
3824 result,
3825 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.sqrt()))
3826 );
3827 }
3828
3829 #[test]
3830 fn try_sqrt() {
3831 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
3832 let result = value.clone().try_sqrt().unwrap();
3833 assert_eq!(
3834 result,
3835 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.sqrt()))
3836 );
3837
3838 assert!(RealRug::<PRECISION>(Float::with_val(PRECISION, -4.0))
3839 .try_sqrt()
3840 .is_err())
3841 }
3842
3843 #[test]
3844 fn test_tan_() {
3845 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3846 let result = value.clone().tan_();
3847 assert_eq!(
3848 result,
3849 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.tan()))
3850 );
3851 }
3852
3853 #[test]
3854 fn test_tanh_() {
3855 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
3856 let result = value.clone().tanh_();
3857 assert_eq!(
3858 result,
3859 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.tanh()))
3860 );
3861 }
3862
3863 #[test]
3864 fn test_mul_add_() {
3865 let a = RealRug::<PRECISION>(Float::with_val(PRECISION, 2.0));
3866 let b = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.0));
3867 let c = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
3868 let result = a.clone().mul_add(&b, &c);
3869 assert_eq!(result, RealRug::<PRECISION>(a.0.clone() * b.0 + c.0));
3870 }
3871 }
3872
3873 mod complex {
3874 use super::*;
3875 use rug::Complex;
3876 use rug::Float;
3877
3878 #[test]
3879 fn test_acos_() {
3880 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3881 let result = value.clone().acos_();
3882 assert_eq!(
3883 result,
3884 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.acos()))
3885 );
3886 }
3887
3888 #[test]
3889 fn test_acosh_() {
3890 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (1.5, 0.5)));
3891 let result = value.clone().acosh_();
3892 assert_eq!(
3893 result,
3894 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.acosh()))
3895 );
3896 }
3897
3898 #[test]
3899 fn test_asin_() {
3900 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3901 let result = value.clone().asin_();
3902 assert_eq!(
3903 result,
3904 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.asin()))
3905 );
3906 }
3907
3908 #[test]
3909 fn test_asinh_() {
3910 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3911 let result = value.clone().asinh_();
3912 assert_eq!(
3913 result,
3914 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.asinh()))
3915 );
3916 }
3917
3918 #[test]
3919 fn test_atan_() {
3920 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3921 let result = value.clone().atan_();
3922 assert_eq!(
3923 result,
3924 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.atan()))
3925 );
3926 }
3927
3928 #[test]
3929 fn test_atanh_() {
3930 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3931 let result = value.clone().atanh_();
3932 assert_eq!(
3933 result,
3934 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.atanh()))
3935 );
3936 }
3937
3938 #[test]
3939 fn test_cos_() {
3940 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3941 let result = value.clone().cos_();
3942 assert_eq!(
3943 result,
3944 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.cos()))
3945 );
3946 }
3947
3948 #[test]
3949 fn test_cosh_() {
3950 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3951 let result = value.clone().cosh_();
3952 assert_eq!(
3953 result,
3954 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.cosh()))
3955 );
3956 }
3957
3958 #[test]
3959 fn test_exp_() {
3960 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3961 let result = value.clone().exp_();
3962 print!("result = {:?}", result);
3963 assert_eq!(
3964 result,
3965 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.exp()))
3966 );
3967 }
3968
3969 #[test]
3970 fn test_is_finite_() {
3971 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3972 assert!(value.is_finite_());
3973
3974 let value = ComplexRug::<PRECISION>(Complex::with_val(
3975 100,
3976 (Float::with_val(PRECISION, f64::INFINITY), 0.5),
3977 ));
3978 assert!(!value.is_finite_());
3979 }
3980
3981 #[test]
3982 fn test_is_infinite_() {
3983 let value = ComplexRug::<PRECISION>(Complex::with_val(
3984 100,
3985 (Float::with_val(PRECISION, f64::INFINITY), 0.5),
3986 ));
3987 assert!(value.is_infinite_());
3988
3989 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
3990 assert!(!value.is_infinite_());
3991 }
3992
3993 #[test]
3994 fn test_ln_() {
3995 let value = ComplexRug::<PRECISION>(Complex::with_val(
3996 PRECISION,
3997 (2.718281828459045, 1.0),
3998 ));
3999 let result = value.clone().ln_();
4000 println!("result = {:?}", result);
4001 assert_eq!(
4002 result,
4003 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.ln()))
4004 );
4005 }
4006
4007 #[test]
4008 fn test_log10_() {
4009 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (10.0, 1.0)));
4010 let result = value.clone().log10_();
4011 println!("result = {:?}", result);
4012 assert_eq!(
4013 result,
4014 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.log10()))
4015 );
4016 }
4017
4018 #[test]
4019 fn test_log2_() {
4020 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (8.0, 1.0)));
4021 let result = value.clone().log2_();
4022 println!("result = {:?}", result);
4023 assert_eq!(
4024 result,
4025 ComplexRug::<PRECISION>(Complex::with_val(
4026 PRECISION,
4027 value.0.log10() / rug::Float::with_val(PRECISION, 2.).log10()
4028 ))
4029 );
4030 }
4031
4032 #[test]
4033 fn test_recip_() {
4034 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (2.0, 0.0)));
4035 let result = value.clone().try_reciprocal().unwrap();
4036 assert_eq!(
4037 result,
4038 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.recip()))
4039 );
4040 }
4041
4042 #[test]
4043 fn test_sin_() {
4044 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
4045 let result = value.clone().sin_();
4046 assert_eq!(
4047 result,
4048 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.sin()))
4049 );
4050 }
4051
4052 #[test]
4053 fn test_sinh_() {
4054 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
4055 let result = value.clone().sinh_();
4056 assert_eq!(
4057 result,
4058 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.sinh()))
4059 );
4060 }
4061
4062 #[test]
4063 fn sqrt() {
4064 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (4.0, 1.0)));
4065 let result = value.clone().sqrt();
4066 assert_eq!(
4067 result,
4068 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.sqrt()))
4069 );
4070 }
4071
4072 #[test]
4073 fn try_sqrt() {
4074 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (4.0, 1.0)));
4075 let result = value.clone().try_sqrt().unwrap();
4076 assert_eq!(
4077 result,
4078 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.sqrt()))
4079 );
4080 }
4081
4082 #[test]
4083 fn test_tan_() {
4084 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
4085 let result = value.clone().tan_();
4086 assert_eq!(
4087 result,
4088 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.tan()))
4089 );
4090 }
4091
4092 #[test]
4093 fn test_tanh_() {
4094 let value = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (0.5, 0.5)));
4095 let result = value.clone().tanh_();
4096 assert_eq!(
4097 result,
4098 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, value.0.tanh()))
4099 );
4100 }
4101
4102 #[test]
4103 fn test_mul_add_() {
4104 let a = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (2.0, 1.0)));
4105 let b = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (3.0, 1.0)));
4106 let c = ComplexRug::<PRECISION>(Complex::with_val(PRECISION, (4.0, 1.0)));
4107 let result = a.clone().mul_add(&b, &c);
4108 assert_eq!(
4109 result,
4110 ComplexRug::<PRECISION>(Complex::with_val(PRECISION, a.0 * b.0 + c.0))
4111 );
4112 }
4113 }
4114 }
4115 }
4116
4117 mod functions_real_type {
4118 use super::*;
4119
4120 mod native64 {
4121 use super::*;
4122
4123 #[test]
4124 fn test_atan2_() {
4125 let a: f64 = 27.0;
4126 let b: f64 = 13.0;
4127
4128 let result = a.atan2_(&b);
4129 assert_eq!(result, a.atan2(b));
4130 }
4131
4132 #[test]
4133 fn test_ceil_() {
4134 let value: f64 = 3.7;
4135 let result = value.ceil_();
4136 assert_eq!(result, value.ceil());
4137 }
4138
4139 #[test]
4140 fn test_clamp_() {
4141 let value: f64 = 5.0;
4142 let min: f64 = 3.0;
4143 let max: f64 = 7.0;
4144 let result = value.clamp_(&min, &max);
4145 assert_eq!(result, value.clamp(min, max));
4146 }
4147
4148 #[test]
4149 fn test_classify_() {
4150 let value: f64 = 3.7;
4151 let result = value.classify_();
4152 assert_eq!(result, value.classify());
4153 }
4154
4155 #[test]
4156 fn test_copysign_() {
4157 let value: f64 = 3.5;
4158 let sign: f64 = -1.0;
4159 let result = value.copysign_(&sign);
4160 assert_eq!(result, value.copysign(sign));
4161 }
4162
4163 #[test]
4164 fn test_epsilon_() {
4165 let eps = f64::epsilon_();
4166 assert_eq!(eps, f64::EPSILON);
4167 }
4168
4169 #[test]
4170 fn test_exp_m1_() {
4171 let value: f64 = 0.5;
4172 let result = value.exp_m1_();
4173 assert_eq!(result, value.exp_m1());
4174 }
4175
4176 #[test]
4177 fn test_floor_() {
4178 let value: f64 = 3.7;
4179 let result = value.floor_();
4180 assert_eq!(result, value.floor());
4181 }
4182
4183 #[test]
4184 fn test_fract_() {
4185 let value: f64 = 3.7;
4186 let result = value.fract_();
4187 assert_eq!(result, value.fract());
4188 }
4189
4190 #[test]
4191 fn test_hypot_() {
4192 let a: f64 = 3.0;
4193 let b: f64 = 4.0;
4194 let result = a.hypot_(&b);
4195 assert_eq!(result, a.hypot(b));
4196 }
4197
4198 #[test]
4199 fn test_infinity_() {
4200 let inf = f64::infinity_();
4201 assert_eq!(inf, f64::INFINITY);
4202 }
4203
4204 #[test]
4205 fn test_is_sign_negative_() {
4206 let value: f64 = -1.0;
4207 assert!(value.is_sign_negative_());
4208
4209 let value: f64 = -0.0;
4210 assert!(value.is_sign_negative_());
4211
4212 let value: f64 = 0.0;
4213 assert!(!value.is_sign_negative_());
4214
4215 let value: f64 = 1.0;
4216 assert!(!value.is_sign_negative_());
4217 }
4218
4219 #[test]
4220 fn test_is_sign_positive_() {
4221 let value: f64 = -1.0;
4222 assert!(!value.is_sign_positive_());
4223
4224 let value: f64 = -0.0;
4225 assert!(!value.is_sign_positive_());
4226
4227 let value: f64 = 0.0;
4228 assert!(value.is_sign_positive_());
4229
4230 let value: f64 = 1.0;
4231 assert!(value.is_sign_positive_());
4232 }
4233
4234 #[test]
4235 fn test_ln_1p_() {
4236 let value: f64 = 0.5;
4237 let result = value.ln_1p_();
4238 assert_eq!(result, value.ln_1p());
4239 }
4240
4241 #[test]
4242 fn test_neg_infinity_() {
4243 let inf = f64::neg_infinity_();
4244 assert_eq!(inf, f64::NEG_INFINITY);
4245 }
4246
4247 #[test]
4248 fn test_max_() {
4249 let a: f64 = 3.0;
4250 let b: f64 = 4.0;
4251 let result = a.max_(&b);
4252 assert_eq!(result, a.max(b));
4253 }
4254
4255 #[test]
4256 fn test_min_() {
4257 let a: f64 = 3.0;
4258 let b: f64 = 4.0;
4259 let result = a.min_(&b);
4260 assert_eq!(result, a.min(b));
4261 }
4262
4263 #[test]
4264 fn test_mul_add_mul_mut() {
4265 let mut a: f64 = 2.0;
4266 let b: f64 = 3.0;
4267 let c: f64 = 4.0;
4268 let d: f64 = -1.0;
4269 let result = a.mul_add_mul_mut_(&b, &c, &d);
4270 assert_eq!(result, a.mul_add_assign(b, c * d));
4271 }
4272
4273 #[test]
4274 fn test_mul_sub_mul_mut() {
4275 let mut a: f64 = 2.0;
4276 let b: f64 = 3.0;
4277 let c: f64 = 4.0;
4278 let d: f64 = -1.0;
4279 let result = a.mul_sub_mul_mut_(&b, &c, &d);
4280 assert_eq!(result, a.mul_add_assign(b, -c * d));
4281 }
4282
4283 #[test]
4284 fn test_negative_one_() {
4285 let value = f64::negative_one_();
4286 assert_eq!(value, -1.0);
4287 }
4288
4289 #[test]
4290 fn test_one_() {
4291 let value = f64::one();
4292 assert_eq!(value, 1.0);
4293 }
4294
4295 #[test]
4296 fn test_round_() {
4297 let value: f64 = 3.5;
4298 let result = value.round_();
4299 assert_eq!(result, value.round());
4300 }
4301
4302 #[test]
4303 fn test_round_ties_even_() {
4304 let value: f64 = 3.5;
4305 let result = value.round_ties_even_();
4306 assert_eq!(result, value.round_ties_even());
4307 }
4308
4309 #[test]
4310 fn test_signum_() {
4311 let value: f64 = -3.5;
4312 let result = value.signum_();
4313 assert_eq!(result, value.signum());
4314 }
4315
4316 #[test]
4317 fn test_total_cmp_() {
4318 let a: f64 = 3.0;
4319 let b: f64 = 4.0;
4320 let result = a.total_cmp_(&b);
4321 assert_eq!(result, a.total_cmp(&b));
4322 }
4323
4324 #[test]
4325 fn test_try_from_64_() {
4326 let result = f64::try_from_f64_(3.7);
4327 assert!(result.is_ok());
4328 }
4329
4330 #[test]
4331 fn test_try_from_64_error_infinite() {
4332 let result = f64::try_from_f64_(f64::INFINITY);
4333 assert!(result.is_err());
4334 }
4335
4336 #[test]
4337 fn test_try_from_64_error_nan() {
4338 let result = f64::try_from_f64_(f64::NAN);
4339 assert!(result.is_err());
4340 }
4341
4342 #[test]
4343 fn test_trunc_() {
4344 let value: f64 = 3.7;
4345 let result = value.trunc_();
4346 assert_eq!(result, value.trunc());
4347 }
4348
4349 #[test]
4350 fn test_two_() {
4351 let value = f64::two_();
4352 assert_eq!(value, 2.0);
4353 }
4354 }
4355
4356 #[cfg(feature = "rug")]
4357 mod rug100 {
4358 use super::*;
4359 use rug::{float, Float};
4360
4361 const PRECISION: u32 = 100;
4362
4363 #[test]
4364 fn test_atan2_() {
4365 let a = RealRug::<PRECISION>(Float::with_val(PRECISION, 27.0));
4366 let b = RealRug::<PRECISION>(Float::with_val(PRECISION, 13.0));
4367 let result = a.clone().atan2_(&b);
4368 assert_eq!(
4369 result,
4370 RealRug::<PRECISION>(Float::with_val(PRECISION, a.0.atan2(&b.0)))
4371 );
4372 }
4373
4374 #[test]
4375 fn test_ceil_() {
4376 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.7));
4377 let result = value.clone().ceil_();
4378 assert_eq!(
4379 result,
4380 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.ceil()))
4381 );
4382 }
4383
4384 #[test]
4385 fn test_clamp_() {
4386 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 5.0));
4387 let min = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.0));
4388 let max = RealRug::<PRECISION>(Float::with_val(PRECISION, 7.0));
4389 let result = value.clone().clamp_(&min, &max);
4390 assert_eq!(
4391 result,
4392 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.clamp(&min.0, &max.0)))
4393 );
4394 }
4395
4396 #[test]
4397 fn test_classify_() {
4398 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.7));
4399 let result = value.classify_();
4400 assert_eq!(result, value.0.classify());
4401 }
4402
4403 #[test]
4404 fn test_copysign_() {
4405 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.5));
4406 let sign = RealRug::<PRECISION>(Float::with_val(PRECISION, -1.0));
4407 let result = value.clone().copysign_(&sign);
4408 assert_eq!(
4409 result,
4410 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.copysign(&sign.0)))
4411 );
4412 }
4413
4414 #[test]
4415 fn test_epsilon_() {
4416 let rug_eps = rug::Float::u_pow_u(2, PRECISION - 1)
4417 .complete(PRECISION.into())
4418 .recip();
4419 println!("eps: {}", rug_eps);
4420
4421 let eps = RealRug::<PRECISION>::epsilon_();
4422 assert_eq!(eps, RealRug::<PRECISION>(rug_eps.clone()));
4423
4424 let mut new_eps = Float::with_val(PRECISION, 1.);
4426 new_eps.next_up();
4427 new_eps -= Float::with_val(PRECISION, 1.);
4428 assert_eq!(new_eps, rug_eps.clone());
4429
4430 println!("new_eps: {}", new_eps);
4431
4432 let one = RealRug::<PRECISION>::one();
4433 let result = RealRug::<PRECISION>(new_eps / Float::with_val(PRECISION, 2.)) + &one;
4434 assert_eq!(result, one);
4435 }
4436
4437 #[test]
4438 fn test_exp_m1_() {
4439 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
4440 let result = value.clone().exp_m1_();
4441 assert_eq!(
4442 result,
4443 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.exp_m1()))
4444 );
4445 }
4446
4447 #[test]
4448 fn test_floor_() {
4449 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.7));
4450 let result = value.clone().floor_();
4451 assert_eq!(
4452 result,
4453 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.floor()))
4454 );
4455 }
4456
4457 #[test]
4458 fn test_fract_() {
4459 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.7));
4460 let result = value.clone().fract_();
4461 assert_eq!(
4462 result,
4463 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.fract()))
4464 );
4465 }
4466
4467 #[test]
4468 fn test_hypot_() {
4469 let a = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.0));
4470 let b = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
4471 let result = a.clone().hypot_(&b);
4472 assert_eq!(
4473 result,
4474 RealRug::<PRECISION>(Float::with_val(PRECISION, a.0.hypot(&b.0)))
4475 );
4476 }
4477
4478 #[test]
4479 fn test_infinity_() {
4480 let inf = RealRug::<PRECISION>::infinity_();
4481 assert_eq!(
4482 inf,
4483 RealRug::<PRECISION>(Float::with_val(PRECISION, float::Special::Infinity))
4484 );
4485 }
4486
4487 #[test]
4488 fn test_is_sign_negative_() {
4489 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, -1.0));
4490 assert!(value.is_sign_negative_());
4491
4492 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, -0.0));
4493 assert!(value.is_sign_negative_());
4494
4495 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.0));
4496 assert!(!value.is_sign_negative_());
4497
4498 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 1.0));
4499 assert!(!value.is_sign_negative_());
4500 }
4501
4502 #[test]
4503 fn test_is_sign_positive_() {
4504 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, -1.0));
4505 assert!(!value.is_sign_positive_());
4506
4507 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, -0.0));
4508 assert!(!value.is_sign_positive_());
4509
4510 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.0));
4511 assert!(value.is_sign_positive_());
4512
4513 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 1.0));
4514 assert!(value.is_sign_positive_());
4515 }
4516
4517 #[test]
4518 fn test_ln_1p_() {
4519 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 0.5));
4520 let result = value.clone().ln_1p_();
4521 assert_eq!(
4522 result,
4523 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.ln_1p()))
4524 );
4525 }
4526
4527 #[test]
4528 fn test_neg_infinity_() {
4529 let inf = RealRug::<PRECISION>::neg_infinity_();
4530 assert_eq!(
4531 inf,
4532 RealRug::<PRECISION>(Float::with_val(PRECISION, float::Special::NegInfinity))
4533 );
4534 }
4535
4536 #[test]
4537 fn test_max_() {
4538 let a = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.0));
4539 let b = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
4540 let result = a.clone().max_(&b);
4541 assert_eq!(
4542 result,
4543 RealRug::<PRECISION>(Float::with_val(PRECISION, a.0.max(&b.0)))
4544 );
4545 }
4546
4547 #[test]
4548 fn test_min_() {
4549 let a = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.0));
4550 let b = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
4551 let result = a.clone().min_(&b);
4552 assert_eq!(
4553 result,
4554 RealRug::<PRECISION>(Float::with_val(PRECISION, a.0.min(&b.0)))
4555 );
4556 }
4557
4558 #[test]
4559 fn test_mul_add_mul_mut() {
4560 let a = RealRug::<PRECISION>(Float::with_val(PRECISION, 2.0));
4561 let b = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.0));
4562 let c = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
4563 let d = RealRug::<PRECISION>(Float::with_val(PRECISION, -1.0));
4564 let mut result = a.clone();
4565 result.mul_add_mul_mut_(&b, &c, &d);
4566 assert_eq!(
4567 result,
4568 RealRug::<PRECISION>(Float::with_val(
4569 PRECISION,
4570 a.0.mul_add(&b.0, &(c.0 * &d.0))
4571 ))
4572 );
4573 }
4574
4575 #[test]
4576 fn test_mul_sub_mul_mut() {
4577 let a = RealRug::<PRECISION>(Float::with_val(PRECISION, 2.0));
4578 let b = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.0));
4579 let c = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
4580 let d = RealRug::<PRECISION>(Float::with_val(PRECISION, -1.0));
4581 let mut result = a.clone();
4582 result.mul_sub_mul_mut_(&b, &c, &d);
4583 assert_eq!(
4584 result,
4585 RealRug::<PRECISION>(Float::with_val(
4586 PRECISION,
4587 a.0.mul_add(&b.0, &(-c.0 * &d.0))
4588 ))
4589 );
4590 }
4591
4592 #[test]
4593 fn test_negative_one_() {
4594 let value = RealRug::<PRECISION>::negative_one_();
4595 assert_eq!(
4596 value,
4597 RealRug::<PRECISION>(Float::with_val(PRECISION, -1.0))
4598 );
4599 }
4600
4601 #[test]
4602 fn test_one_() {
4603 let value = RealRug::<PRECISION>::one();
4604 assert_eq!(value, RealRug::<PRECISION>(Float::with_val(PRECISION, 1.0)));
4605 }
4606
4607 #[test]
4608 fn test_round_() {
4609 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.5));
4610 let result = value.clone().round_();
4611 assert_eq!(
4612 result,
4613 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.round()))
4614 );
4615 }
4616
4617 #[test]
4618 fn test_round_ties_even_() {
4619 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.5));
4620 let result = value.clone().round_ties_even_();
4621 assert_eq!(
4622 result,
4623 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.round_even()))
4624 );
4625 }
4626
4627 #[test]
4628 fn test_signum_() {
4629 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, -3.5));
4630 let result = value.clone().signum_();
4631 assert_eq!(
4632 result,
4633 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.signum()))
4634 );
4635 }
4636
4637 #[test]
4638 fn test_total_cmp_() {
4639 let a = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.0));
4640 let b = RealRug::<PRECISION>(Float::with_val(PRECISION, 4.0));
4641 let result = a.total_cmp_(&b);
4642 assert_eq!(result, a.0.total_cmp(&b.0));
4643 }
4644
4645 #[test]
4646 fn test_try_from_64_() {
4647 let result = RealRug::<PRECISION>::try_from_f64_(3.7);
4648 assert!(result.is_ok());
4649 }
4650
4651 #[test]
4652 fn test_try_from_64_error_infinite() {
4653 let result = RealRug::<PRECISION>::try_from_f64_(f64::INFINITY);
4654 assert!(result.is_err());
4655 }
4656
4657 #[test]
4658 fn test_try_from_64_error_nan() {
4659 let result = RealRug::<PRECISION>::try_from_f64_(f64::NAN);
4660 assert!(result.is_err());
4661 }
4662
4663 #[test]
4664 fn test_trunc_() {
4665 let value = RealRug::<PRECISION>(Float::with_val(PRECISION, 3.7));
4666 let result = value.clone().trunc_();
4667 assert_eq!(
4668 result,
4669 RealRug::<PRECISION>(Float::with_val(PRECISION, value.0.trunc()))
4670 );
4671 }
4672
4673 #[test]
4674 fn test_two_() {
4675 let value = RealRug::<PRECISION>::two_();
4676 assert_eq!(value, RealRug::<PRECISION>(Float::with_val(PRECISION, 2.0)));
4677 }
4678 }
4679 }
4680}