1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use wolfram_library_link::{self as wll, NumericArray, NumericArrayKind};

/// This function is loaded by evaluating:
///
/// ```wolfram
/// LibraryFunctionLoad[
///     "/path/to/libnumeric_arrays.dylib",
///     "sum_int_numeric_array",
///     {NumericArray},
///     Integer
/// ]
/// ```
#[wll::export]
fn sum_int_numeric_array(na: &NumericArray) -> i64 {
    #[rustfmt::skip]
    let sum: i64 = match na.kind() {
        NumericArrayKind::Bit8(na) => na.as_slice().into_iter().copied().map(i64::from).sum(),
        NumericArrayKind::Bit16(na) => na.as_slice().into_iter().copied().map(i64::from).sum(),
        NumericArrayKind::Bit32(na) => na.as_slice().into_iter().copied().map(i64::from).sum(),
        NumericArrayKind::Bit64(na) => na.as_slice().into_iter().sum(),
        NumericArrayKind::UBit8(na) => na.as_slice().into_iter().copied().map(i64::from).sum(),
        NumericArrayKind::UBit16(na) => na.as_slice().into_iter().copied().map(i64::from).sum(),
        NumericArrayKind::UBit32(na) => na.as_slice().into_iter().copied().map(i64::from).sum(),
        NumericArrayKind::UBit64(na) => {
            match i64::try_from(na.as_slice().into_iter().sum::<u64>()) {
                Ok(sum) => sum,
                Err(_) => panic!("NumericArray UnsignedInteger64 sum overflows i64"),
            }
        },

        NumericArrayKind::Real32(_)
        | NumericArrayKind::Real64(_)
        | NumericArrayKind::ComplexReal64(_) => panic!(
            "sum_int_numeric_array cannot handle non-integer data type: {:?}",
            na.data_type()
        ),
    };

    sum
}

#[wll::export]
fn sum_real_numeric_array(na: &NumericArray) -> f64 {
    let sum: f64 = match na.kind() {
        NumericArrayKind::Real32(na) => {
            na.as_slice().into_iter().copied().map(f64::from).sum()
        },
        NumericArrayKind::Real64(na) => na.as_slice().into_iter().copied().sum(),
        _ => panic!(
            "sum_real_numeric_array cannot handle non-real data type: {:?}",
            na.data_type()
        ),
    };

    sum
}