rustymath-kernels 0.1.59

Resolved numerical kernels over Rustymath formulas and storage.
Documentation
use super::*;

pub(super) fn map_complex<K, F, const N: usize>(
    object: &K, variant: crate::domain::Variant, inputs: Inputs<'_, '_>, range: std::ops::Range<usize>, ops: &NativeOps<{ FUSED }>,
    slice: Option<crate::facts::Slice<K, num_complex::Complex<F>, N, ()>>, judge: crate::domain::Variant, output: &mut Output<'_, '_>) -> Result<(), Error>
where K: crate::facts::Formula<N>, F: crate::Native + crate::buffer::Cast + OutputItem, num_complex::Complex<F>: crate::buffer::Cast + OutputItem {
    let value = |x| object.complex(ops, x).unwrap_or(num_complex::Complex::new(F::zero(), F::zero()));
    let invalid = |x, r| (!complex_valid::<K, F, N>(ops, x, r)).then_some(Kind::Domain);
    if const { K::BOOLEAN } {
        map_values::<num_complex::Complex<F>, bool, N>(
            inputs, range, variant.checked, judge.checked, output, |x| value(x).re != F::zero(),
            |x, r| invalid(x, num_complex::Complex::new(if r { F::one() } else { F::zero() }, F::zero())))
    } else if output.result_dtype.is_real() {
        map_values::<num_complex::Complex<F>, F, N>(
            inputs, range, variant.checked, judge.checked, output, |x| value(x).re, |x, r| invalid(x, num_complex::Complex::new(r, F::zero())))
    } else {
        map_written::<num_complex::Complex<F>, num_complex::Complex<F>, N>(inputs, range, variant.checked, judge.checked, output, |args, n, out| {
            if let Some(slice) = slice { slice(object, ops, *args, n, out); }
            else { crate::slice::mapped(args, n, out, #[inline(always)] |x| (value(x), true)); }
        }, invalid)
    }
}

/// Complex results from real arguments through a native slice, or `Formula::real_complex` with `Formula::complex` for the items it declines.
pub(super) fn map_real_complex<K, F, const N: usize>(
    object: &K, variant: crate::domain::Variant, inputs: Inputs<'_, '_>, range: std::ops::Range<usize>, ops: &NativeOps<{ FUSED }>,
    slice: Option<crate::facts::Slice<K, F, N, (), num_complex::Complex<F>>>, output: &mut Output<'_, '_>
) -> Result<(), Error> where K: crate::facts::Formula<N>, F: crate::Native + crate::buffer::Cast, num_complex::Complex<F>: OutputItem {
    map_blocks::<F, num_complex::Complex<F>, N>(inputs, range, variant.checked, output, &|args, n, out| {
        if let Some(slice) = slice { slice(object, ops, args, n, out); return Ok(()); }
        let nan = num_complex::Complex::new(F::nan(), F::nan());
        if !crate::slice::mapped(&args, n, out, #[inline(always)] |x| object.real_complex(ops, x).map_or((nan, false), |z| (z, true))) {
            for (i, z) in unsafe { crate::slice::written(&mut out[..n]) }.iter_mut().enumerate() {
                let x = std::array::from_fn(|j| args[j].nth(i));
                if object.real_complex(ops, x).is_none() { *z = object.complex(ops, x.map(|v| num_complex::Complex::new(v, F::zero()))).unwrap_or(nan); }
            }
        }
        Ok(())
    })
}