scirs2_core/ndarray_ext/elementwise/
functions_5.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use crate::numeric::Float;
6use crate::simd_ops::{AutoOptimizer, SimdUnifiedOps};
7use ::ndarray::{Array1, ArrayView1};
8
9/// SIMD-accelerated inverse square root: 1/sqrt(x)
10///
11/// Computes the reciprocal of the square root for each element.
12/// This operation is fundamental in graphics and physics simulations.
13///
14/// # Arguments
15/// * `a` - Input values (should be positive)
16///
17/// # Returns
18/// Array of 1/sqrt(x) values
19/// - Returns INFINITY for x = 0
20/// - Returns NaN for x < 0
21///
22/// # Examples
23/// ```
24/// use scirs2_core::ndarray::{array, Array1};
25/// use scirs2_core::ndarray_ext::elementwise::rsqrt_simd;
26///
27/// let x = array![1.0_f64, 4.0, 9.0, 16.0];
28///
29/// let result = rsqrt_simd::<f64>(&x.view());
30/// assert!((result[0] - 1.0).abs() < 1e-14);     // 1/sqrt(1) = 1
31/// assert!((result[1] - 0.5).abs() < 1e-14);     // 1/sqrt(4) = 0.5
32/// assert!((result[2] - 1.0/3.0).abs() < 1e-14); // 1/sqrt(9) = 1/3
33/// assert!((result[3] - 0.25).abs() < 1e-14);    // 1/sqrt(16) = 0.25
34/// ```
35///
36/// # Use Cases
37/// - Vector normalization: v_normalized = v * rsqrt(dot(v, v))
38/// - Quaternion normalization in 3D graphics
39/// - Inverse distance weighting
40/// - Fast approximate physics simulations
41pub fn rsqrt_simd<F>(a: &ArrayView1<F>) -> Array1<F>
42where
43    F: Float + SimdUnifiedOps,
44{
45    if a.is_empty() {
46        return Array1::zeros(0);
47    }
48    let optimizer = AutoOptimizer::new();
49    if optimizer.should_use_simd(a.len()) {
50        return F::simd_rsqrt(a);
51    }
52    F::simd_rsqrt(a)
53}
54/// SIMD-accelerated simultaneous sin and cos computation
55///
56/// Computes both sine and cosine of each element in a single pass.
57/// This is more efficient than calling sin and cos separately because
58/// many implementations can compute both with minimal additional overhead.
59///
60/// # Arguments
61/// * `a` - Input angles in radians
62///
63/// # Returns
64/// Tuple of (sin_array, cos_array)
65///
66/// # Examples
67/// ```
68/// use scirs2_core::ndarray::{array, Array1};
69/// use scirs2_core::ndarray_ext::elementwise::sincos_simd;
70/// use std::f64::consts::PI;
71///
72/// let x = array![0.0_f64, PI/6.0, PI/4.0, PI/2.0];
73///
74/// let (sin_result, cos_result) = sincos_simd::<f64>(&x.view());
75/// assert!((sin_result[0] - 0.0).abs() < 1e-14);        // sin(0) = 0
76/// assert!((cos_result[0] - 1.0).abs() < 1e-14);        // cos(0) = 1
77/// assert!((sin_result[1] - 0.5).abs() < 1e-14);        // sin(π/6) = 0.5
78/// assert!((sin_result[3] - 1.0).abs() < 1e-14);        // sin(π/2) = 1
79/// assert!(cos_result[3].abs() < 1e-14);                // cos(π/2) ≈ 0
80/// ```
81///
82/// # Use Cases
83/// - Rotation matrices (need both sin and cos)
84/// - Complex number operations: e^(iθ) = cos(θ) + i·sin(θ)
85/// - Fourier transform calculations
86/// - Wave simulations
87/// - Animation and interpolation (circular motion)
88pub fn sincos_simd<F>(a: &ArrayView1<F>) -> (Array1<F>, Array1<F>)
89where
90    F: Float + SimdUnifiedOps,
91{
92    if a.is_empty() {
93        return (Array1::zeros(0), Array1::zeros(0));
94    }
95    let optimizer = AutoOptimizer::new();
96    if optimizer.should_use_simd(a.len()) {
97        return F::simd_sincos(a);
98    }
99    F::simd_sincos(a)
100}
101/// SIMD-accelerated numerically stable exp(x) - 1
102///
103/// Computes exp(x) - 1 accurately for small x values where the direct
104/// calculation `exp(x) - 1` would suffer from catastrophic cancellation.
105/// For |x| < 1e-10, the result is approximately x (Taylor expansion).
106///
107/// # Arguments
108/// * `a` - Input values
109///
110/// # Returns
111/// Array of exp(x) - 1 values
112///
113/// # Examples
114/// ```
115/// use scirs2_core::ndarray::{array, Array1};
116/// use scirs2_core::ndarray_ext::elementwise::expm1_simd;
117///
118/// let x = array![0.0_f64, 1e-15, 1.0, -1.0];
119///
120/// let result = expm1_simd::<f64>(&x.view());
121/// // exp(0) - 1 = 0
122/// assert!((result[0] - 0.0).abs() < 1e-14);
123/// // For small x: exp(x) - 1 ≈ x
124/// assert!((result[1] - 1e-15).abs() < 1e-29);
125/// // exp(1) - 1 ≈ 1.718
126/// assert!((result[2] - (1.0_f64.exp() - 1.0)).abs() < 1e-14);
127/// ```
128///
129/// # Use Cases
130/// - Financial calculations (compound interest for small rates)
131/// - Numerical integration (avoiding cancellation errors)
132/// - Statistical distributions (Poisson, exponential)
133/// - Machine learning (softplus: log(1 + exp(x)))
134pub fn expm1_simd<F>(a: &ArrayView1<F>) -> Array1<F>
135where
136    F: Float + SimdUnifiedOps,
137{
138    if a.is_empty() {
139        return Array1::zeros(0);
140    }
141    let optimizer = AutoOptimizer::new();
142    if optimizer.should_use_simd(a.len()) {
143        return F::simd_expm1(a);
144    }
145    F::simd_expm1(a)
146}
147/// SIMD-accelerated numerically stable ln(1 + x)
148///
149/// Computes ln(1 + x) accurately for small x values where the direct
150/// calculation `(1 + x).ln()` would suffer from catastrophic cancellation.
151/// For |x| < 1e-10, the result is approximately x - x²/2 (Taylor expansion).
152///
153/// # Arguments
154/// * `a` - Input values (should be > -1)
155///
156/// # Returns
157/// Array of ln(1 + x) values
158/// - Returns -∞ for x = -1
159/// - Returns NaN for x < -1
160///
161/// # Examples
162/// ```
163/// use scirs2_core::ndarray::{array, Array1};
164/// use scirs2_core::ndarray_ext::elementwise::log1p_simd;
165///
166/// let x = array![0.0_f64, 1e-15, 1.0, -0.5];
167///
168/// let result = log1p_simd::<f64>(&x.view());
169/// // ln(1 + 0) = 0
170/// assert!((result[0] - 0.0).abs() < 1e-14);
171/// // For small x: ln(1 + x) ≈ x
172/// assert!((result[1] - 1e-15).abs() < 1e-29);
173/// // ln(2) ≈ 0.693
174/// assert!((result[2] - 2.0_f64.ln()).abs() < 1e-14);
175/// ```
176///
177/// # Use Cases
178/// - Log-probability calculations (log(1 - p) for small p)
179/// - Numerical integration
180/// - Statistical distributions
181/// - Machine learning (binary cross-entropy: -y·log(p) - (1-y)·log(1-p))
182pub fn log1p_simd<F>(a: &ArrayView1<F>) -> Array1<F>
183where
184    F: Float + SimdUnifiedOps,
185{
186    if a.is_empty() {
187        return Array1::zeros(0);
188    }
189    let optimizer = AutoOptimizer::new();
190    if optimizer.should_use_simd(a.len()) {
191        return F::simd_log1p(a);
192    }
193    F::simd_log1p(a)
194}
195/// SIMD-accelerated element-wise clipping (clamping)
196///
197/// Clips (limits) each element to be within [min_val, max_val].
198/// Values below min_val become min_val, values above max_val become max_val.
199///
200/// # Arguments
201/// * `a` - Input array
202/// * `min_val` - Minimum value (lower bound)
203/// * `max_val` - Maximum value (upper bound)
204///
205/// # Returns
206/// Array with values clipped to [min_val, max_val]
207///
208/// # Examples
209/// ```
210/// use scirs2_core::ndarray::{array, Array1};
211/// use scirs2_core::ndarray_ext::elementwise::clip_simd;
212///
213/// let x = array![-2.0_f64, -1.0, 0.0, 1.0, 2.0, 3.0];
214///
215/// let result = clip_simd::<f64>(&x.view(), 0.0, 1.0);
216/// assert!((result[0] - 0.0).abs() < 1e-14);  // -2 clipped to 0
217/// assert!((result[2] - 0.0).abs() < 1e-14);  // 0 unchanged
218/// assert!((result[3] - 1.0).abs() < 1e-14);  // 1 unchanged
219/// assert!((result[5] - 1.0).abs() < 1e-14);  // 3 clipped to 1
220/// ```
221///
222/// # Use Cases
223/// - Gradient clipping in neural networks
224/// - Image processing (pixel value clamping)
225/// - Bounded optimization
226/// - Data normalization preprocessing
227pub fn clip_simd<F>(a: &ArrayView1<F>, min_val: F, max_val: F) -> Array1<F>
228where
229    F: Float + SimdUnifiedOps,
230{
231    if a.is_empty() {
232        return Array1::zeros(0);
233    }
234    let optimizer = AutoOptimizer::new();
235    if optimizer.should_use_simd(a.len()) {
236        return F::simd_clip(a, min_val, max_val);
237    }
238    F::simd_clip(a, min_val, max_val)
239}
240/// SIMD-accelerated cumulative sum (prefix sum)
241///
242/// Computes the cumulative sum of elements. `result[i] = sum(a[0..=i])`
243///
244/// # Arguments
245/// * `a` - Input array
246///
247/// # Returns
248/// Array of cumulative sums
249///
250/// # Examples
251/// ```
252/// use scirs2_core::ndarray::{array, Array1};
253/// use scirs2_core::ndarray_ext::elementwise::cumsum_simd;
254///
255/// let x = array![1.0_f64, 2.0, 3.0, 4.0, 5.0];
256///
257/// let result = cumsum_simd::<f64>(&x.view());
258/// assert!((result[0] - 1.0).abs() < 1e-14);   // 1
259/// assert!((result[1] - 3.0).abs() < 1e-14);   // 1+2
260/// assert!((result[2] - 6.0).abs() < 1e-14);   // 1+2+3
261/// assert!((result[3] - 10.0).abs() < 1e-14);  // 1+2+3+4
262/// assert!((result[4] - 15.0).abs() < 1e-14);  // 1+2+3+4+5
263/// ```
264///
265/// # Use Cases
266/// - Computing CDF from PDF
267/// - Running totals and statistics
268/// - Parallel prefix algorithms
269/// - Integral image computation
270pub fn cumsum_simd<F>(a: &ArrayView1<F>) -> Array1<F>
271where
272    F: Float + SimdUnifiedOps,
273{
274    if a.is_empty() {
275        return Array1::zeros(0);
276    }
277    let optimizer = AutoOptimizer::new();
278    if optimizer.should_use_simd(a.len()) {
279        return F::simd_cumsum(a);
280    }
281    F::simd_cumsum(a)
282}
283/// SIMD-accelerated cumulative product
284///
285/// Computes the cumulative product of elements. `result[i] = product(a[0..=i])`
286///
287/// # Arguments
288/// * `a` - Input array
289///
290/// # Returns
291/// Array of cumulative products
292///
293/// # Examples
294/// ```
295/// use scirs2_core::ndarray::{array, Array1};
296/// use scirs2_core::ndarray_ext::elementwise::cumprod_simd;
297///
298/// let x = array![1.0_f64, 2.0, 3.0, 4.0];
299///
300/// let result = cumprod_simd::<f64>(&x.view());
301/// assert!((result[0] - 1.0).abs() < 1e-14);   // 1
302/// assert!((result[1] - 2.0).abs() < 1e-14);   // 1*2
303/// assert!((result[2] - 6.0).abs() < 1e-14);   // 1*2*3
304/// assert!((result[3] - 24.0).abs() < 1e-14);  // 1*2*3*4 = 4!
305/// ```
306///
307/// # Use Cases
308/// - Computing factorials and permutations
309/// - Product of survival probabilities
310/// - Chain rule in automatic differentiation
311/// - Compound interest calculations
312pub fn cumprod_simd<F>(a: &ArrayView1<F>) -> Array1<F>
313where
314    F: Float + SimdUnifiedOps,
315{
316    if a.is_empty() {
317        return Array1::zeros(0);
318    }
319    let optimizer = AutoOptimizer::new();
320    if optimizer.should_use_simd(a.len()) {
321        return F::simd_cumprod(a);
322    }
323    F::simd_cumprod(a)
324}
325/// SIMD-accelerated first-order difference
326///
327/// Computes the first-order finite difference: `result[i] = a[i+1] - a[i]`
328/// The output has length n-1 for input of length n.
329///
330/// # Arguments
331/// * `a` - Input array (length >= 2)
332///
333/// # Returns
334/// Array of differences (length n-1)
335///
336/// # Examples
337/// ```
338/// use scirs2_core::ndarray::{array, Array1};
339/// use scirs2_core::ndarray_ext::elementwise::diff_simd;
340///
341/// let x = array![1.0_f64, 3.0, 6.0, 10.0, 15.0];
342///
343/// let result = diff_simd::<f64>(&x.view());
344/// assert_eq!(result.len(), 4);  // n-1 elements
345/// assert!((result[0] - 2.0).abs() < 1e-14);  // 3-1
346/// assert!((result[1] - 3.0).abs() < 1e-14);  // 6-3
347/// assert!((result[2] - 4.0).abs() < 1e-14);  // 10-6
348/// assert!((result[3] - 5.0).abs() < 1e-14);  // 15-10
349/// ```
350///
351/// # Use Cases
352/// - Numerical differentiation
353/// - Detecting changes in time series
354/// - Computing gradients
355/// - Edge detection in signal processing
356pub fn diff_simd<F>(a: &ArrayView1<F>) -> Array1<F>
357where
358    F: Float + SimdUnifiedOps,
359{
360    if a.len() < 2 {
361        return Array1::zeros(0);
362    }
363    let optimizer = AutoOptimizer::new();
364    if optimizer.should_use_simd(a.len()) {
365        return F::simd_diff(a);
366    }
367    F::simd_diff(a)
368}
369/// SIMD-accelerated variance computation
370///
371/// Computes the sample variance: Var(x) = sum((x - mean)²) / (n-1)
372/// Uses Bessel's correction for unbiased estimation.
373///
374/// # Arguments
375/// * `a` - Input array
376///
377/// # Returns
378/// Sample variance of the array
379///
380/// # Examples
381/// ```
382/// use scirs2_core::ndarray::array;
383/// use scirs2_core::ndarray_ext::elementwise::variance_simd;
384///
385/// let x = array![2.0_f64, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0];
386/// let var = variance_simd::<f64>(&x.view());
387/// // Sample variance: sum of squared deviations = 32, n = 8
388/// // var = 32 / (8-1) = 32/7 ≈ 4.571
389/// let expected = 32.0 / 7.0;
390/// assert!((var - expected).abs() < 1e-10);
391/// ```
392///
393/// # Use Cases
394/// - Statistical analysis
395/// - Quality control (process capability)
396/// - Risk assessment (financial variance)
397/// - Feature scaling (standardization)
398pub fn variance_simd<F>(a: &ArrayView1<F>) -> F
399where
400    F: Float + SimdUnifiedOps,
401{
402    if a.is_empty() {
403        return F::zero();
404    }
405    F::simd_variance(a)
406}
407/// SIMD-accelerated standard deviation computation
408///
409/// Computes the sample standard deviation: std = sqrt(sample_variance)
410///
411/// # Arguments
412/// * `a` - Input array
413///
414/// # Returns
415/// Sample standard deviation
416///
417/// # Examples
418/// ```
419/// use scirs2_core::ndarray::array;
420/// use scirs2_core::ndarray_ext::elementwise::std_simd;
421///
422/// let x = array![2.0_f64, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0];
423/// let s = std_simd::<f64>(&x.view());
424/// // Sample std = sqrt(sample variance) = sqrt(32/7) ≈ 2.138
425/// let expected = (32.0_f64 / 7.0).sqrt();
426/// assert!((s - expected).abs() < 1e-10);
427/// ```
428///
429/// # Use Cases
430/// - Volatility measurement in finance
431/// - Error analysis in experiments
432/// - Gaussian distribution parameters
433/// - Confidence interval calculations
434pub fn std_simd<F>(a: &ArrayView1<F>) -> F
435where
436    F: Float + SimdUnifiedOps,
437{
438    if a.is_empty() {
439        return F::zero();
440    }
441    F::simd_std(a)
442}
443/// SIMD-accelerated array sum
444///
445/// Computes the sum of all elements in the array.
446/// Uses Kahan summation for improved numerical accuracy.
447///
448/// # Arguments
449/// * `a` - Input array
450///
451/// # Returns
452/// Sum of all elements
453///
454/// # Examples
455/// ```
456/// use scirs2_core::ndarray::array;
457/// use scirs2_core::ndarray_ext::elementwise::sum_simd;
458///
459/// let x = array![1.0_f64, 2.0, 3.0, 4.0, 5.0];
460/// let s = sum_simd::<f64>(&x.view());
461/// assert!((s - 15.0).abs() < 1e-14);
462/// ```
463///
464/// # Use Cases
465/// - Computing totals
466/// - Mean calculation component
467/// - Probability mass functions
468/// - Integration approximation
469pub fn sum_simd<F>(a: &ArrayView1<F>) -> F
470where
471    F: Float + SimdUnifiedOps,
472{
473    if a.is_empty() {
474        return F::zero();
475    }
476    F::simd_sum(a)
477}
478/// SIMD-accelerated array mean
479///
480/// Computes the arithmetic mean: mean = sum(x) / n
481///
482/// # Arguments
483/// * `a` - Input array
484///
485/// # Returns
486/// Arithmetic mean of elements
487///
488/// # Examples
489/// ```
490/// use scirs2_core::ndarray::array;
491/// use scirs2_core::ndarray_ext::elementwise::mean_simd;
492///
493/// let x = array![1.0_f64, 2.0, 3.0, 4.0, 5.0];
494/// let m = mean_simd::<f64>(&x.view());
495/// assert!((m - 3.0).abs() < 1e-14);
496/// ```
497///
498/// # Use Cases
499/// - Central tendency measurement
500/// - Batch normalization (compute running mean)
501/// - Signal averaging
502/// - Expected value estimation
503pub fn mean_simd<F>(a: &ArrayView1<F>) -> F
504where
505    F: Float + SimdUnifiedOps,
506{
507    if a.is_empty() {
508        return F::zero();
509    }
510    F::simd_mean(a)
511}
512/// SIMD-accelerated weighted sum
513///
514/// Computes sum(values * weights).
515///
516/// # Arguments
517/// * `values` - Values array
518/// * `weights` - Weights array (same length as values)
519///
520/// # Returns
521/// Weighted sum
522///
523/// # Examples
524/// ```
525/// use scirs2_core::ndarray::array;
526/// use scirs2_core::ndarray_ext::elementwise::weighted_sum_simd;
527///
528/// let values = array![10.0_f64, 20.0, 30.0];
529/// let weights = array![0.2_f64, 0.3, 0.5];
530/// let ws = weighted_sum_simd::<f64>(&values.view(), &weights.view());
531/// // 10*0.2 + 20*0.3 + 30*0.5 = 2 + 6 + 15 = 23
532/// assert!((ws - 23.0).abs() < 1e-10);
533/// ```
534///
535/// # Use Cases
536/// - Portfolio valuation
537/// - Weighted regression
538/// - Attention mechanism scores
539/// - Signal filtering
540pub fn weighted_sum_simd<F>(values: &ArrayView1<F>, weights: &ArrayView1<F>) -> F
541where
542    F: Float + SimdUnifiedOps,
543{
544    if values.is_empty() || weights.is_empty() {
545        return F::zero();
546    }
547    F::simd_weighted_sum(values, weights)
548}
549/// SIMD-accelerated weighted mean
550///
551/// Computes sum(values * weights) / sum(weights).
552///
553/// # Arguments
554/// * `values` - Values array
555/// * `weights` - Weights array (same length as values)
556///
557/// # Returns
558/// Weighted mean
559///
560/// # Examples
561/// ```
562/// use scirs2_core::ndarray::array;
563/// use scirs2_core::ndarray_ext::elementwise::weighted_mean_simd;
564///
565/// let values = array![10.0_f64, 20.0, 30.0];
566/// let weights = array![1.0_f64, 2.0, 2.0];
567/// let wm = weighted_mean_simd::<f64>(&values.view(), &weights.view());
568/// // (10*1 + 20*2 + 30*2) / (1+2+2) = (10+40+60)/5 = 22
569/// assert!((wm - 22.0).abs() < 1e-10);
570/// ```
571///
572/// # Use Cases
573/// - Grade point average calculation
574/// - Portfolio weighted return
575/// - Weighted sentiment analysis
576/// - Attention-weighted representations
577pub fn weighted_mean_simd<F>(values: &ArrayView1<F>, weights: &ArrayView1<F>) -> F
578where
579    F: Float + SimdUnifiedOps,
580{
581    if values.is_empty() || weights.is_empty() {
582        return F::zero();
583    }
584    F::simd_weighted_mean(values, weights)
585}
586/// SIMD-accelerated maximum element
587///
588/// Finds the maximum value in the array.
589///
590/// # Arguments
591/// * `a` - Input array
592///
593/// # Returns
594/// Maximum element value
595///
596/// # Examples
597/// ```
598/// use scirs2_core::ndarray::array;
599/// use scirs2_core::ndarray_ext::elementwise::max_element_simd;
600///
601/// let x = array![3.0_f64, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0];
602/// let max = max_element_simd::<f64>(&x.view());
603/// assert!((max - 9.0).abs() < 1e-14);
604/// ```
605///
606/// # Use Cases
607/// - Finding peak values
608/// - Range calculation
609/// - Normalization (min-max scaling)
610/// - Softmax numerator stability
611pub fn max_element_simd<F>(a: &ArrayView1<F>) -> F
612where
613    F: Float + SimdUnifiedOps,
614{
615    if a.is_empty() {
616        return F::neg_infinity();
617    }
618    F::simd_max_element(a)
619}
620/// SIMD-accelerated minimum element
621///
622/// Finds the minimum value in the array.
623///
624/// # Arguments
625/// * `a` - Input array
626///
627/// # Returns
628/// Minimum element value
629///
630/// # Examples
631/// ```
632/// use scirs2_core::ndarray::array;
633/// use scirs2_core::ndarray_ext::elementwise::min_element_simd;
634///
635/// let x = array![3.0_f64, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0];
636/// let min = min_element_simd::<f64>(&x.view());
637/// assert!((min - 1.0).abs() < 1e-14);
638/// ```
639///
640/// # Use Cases
641/// - Finding minimum values
642/// - Range calculation
643/// - Clipping lower bounds
644/// - Outlier detection
645pub fn min_element_simd<F>(a: &ArrayView1<F>) -> F
646where
647    F: Float + SimdUnifiedOps,
648{
649    if a.is_empty() {
650        return F::infinity();
651    }
652    F::simd_min_element(a)
653}
654/// SIMD-accelerated argmax (index of maximum)
655///
656/// Returns the index of the maximum element.
657///
658/// # Arguments
659/// * `a` - Input array
660///
661/// # Returns
662/// Some(index) of maximum element, or None if array is empty
663///
664/// # Examples
665/// ```
666/// use scirs2_core::ndarray::array;
667/// use scirs2_core::ndarray_ext::elementwise::argmax_simd;
668///
669/// let x = array![3.0_f64, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0];
670/// let idx = argmax_simd::<f64>(&x.view());
671/// assert_eq!(idx, Some(5));  // x[5] = 9.0 is the maximum
672/// ```
673///
674/// # Use Cases
675/// - Classification prediction (class with highest probability)
676/// - Finding optimal parameters
677/// - Greedy selection algorithms
678/// - Winner-take-all networks
679pub fn argmax_simd<F>(a: &ArrayView1<F>) -> Option<usize>
680where
681    F: Float + SimdUnifiedOps,
682{
683    if a.is_empty() {
684        return None;
685    }
686    F::simd_argmax(a)
687}
688/// SIMD-accelerated argmin (index of minimum)
689///
690/// Returns the index of the minimum element.
691///
692/// # Arguments
693/// * `a` - Input array
694///
695/// # Returns
696/// Some(index) of minimum element, or None if array is empty
697///
698/// # Examples
699/// ```
700/// use scirs2_core::ndarray::array;
701/// use scirs2_core::ndarray_ext::elementwise::argmin_simd;
702///
703/// let x = array![3.0_f64, 1.0, 4.0, 1.0, 5.0, 9.0, 2.0, 6.0];
704/// let idx = argmin_simd::<f64>(&x.view());
705/// assert_eq!(idx, Some(1));  // x[1] = 1.0 is the minimum (first occurrence)
706/// ```
707///
708/// # Use Cases
709/// - Finding nearest neighbors
710/// - Minimum loss selection
711/// - Optimal path finding
712/// - Resource allocation
713pub fn argmin_simd<F>(a: &ArrayView1<F>) -> Option<usize>
714where
715    F: Float + SimdUnifiedOps,
716{
717    if a.is_empty() {
718        return None;
719    }
720    F::simd_argmin(a)
721}
722/// SIMD-accelerated sum of squares
723///
724/// Computes sum(x²) efficiently.
725///
726/// # Arguments
727/// * `a` - Input array
728///
729/// # Returns
730/// Sum of squared elements
731///
732/// # Examples
733/// ```
734/// use scirs2_core::ndarray::array;
735/// use scirs2_core::ndarray_ext::elementwise::sum_squares_simd;
736///
737/// let x = array![1.0_f64, 2.0, 3.0, 4.0];
738/// let ss = sum_squares_simd::<f64>(&x.view());
739/// // 1 + 4 + 9 + 16 = 30
740/// assert!((ss - 30.0).abs() < 1e-14);
741/// ```
742///
743/// # Use Cases
744/// - L2 norm calculation (sqrt of sum of squares)
745/// - Mean squared error
746/// - Variance computation
747/// - Energy of signal
748pub fn sum_squares_simd<F>(a: &ArrayView1<F>) -> F
749where
750    F: Float + SimdUnifiedOps,
751{
752    if a.is_empty() {
753        return F::zero();
754    }
755    F::simd_sum_squares(a)
756}
757/// SIMD-accelerated sum of cubes
758///
759/// Computes sum(x³) efficiently.
760///
761/// # Arguments
762/// * `a` - Input array
763///
764/// # Returns
765/// Sum of cubed elements
766///
767/// # Examples
768/// ```
769/// use scirs2_core::ndarray::array;
770/// use scirs2_core::ndarray_ext::elementwise::sum_cubes_simd;
771///
772/// let x = array![1.0_f64, 2.0, 3.0];
773/// let sc = sum_cubes_simd::<f64>(&x.view());
774/// // 1 + 8 + 27 = 36
775/// assert!((sc - 36.0).abs() < 1e-14);
776/// ```
777///
778/// # Use Cases
779/// - Higher-order moment calculation
780/// - Skewness estimation
781/// - Cubic interpolation
782/// - Power sum computation
783pub fn sum_cubes_simd<F>(a: &ArrayView1<F>) -> F
784where
785    F: Float + SimdUnifiedOps,
786{
787    if a.is_empty() {
788        return F::zero();
789    }
790    F::simd_sum_cubes(a)
791}
792/// SIMD-accelerated log-sum-exp
793///
794/// Computes log(sum(exp(x))) in a numerically stable way.
795/// Uses the identity: log(sum(exp(x))) = max(x) + log(sum(exp(x - max(x))))
796///
797/// # Arguments
798/// * `a` - Input array
799///
800/// # Returns
801/// Log of sum of exponentials
802///
803/// # Examples
804/// ```
805/// use scirs2_core::ndarray::array;
806/// use scirs2_core::ndarray_ext::elementwise::log_sum_exp_simd;
807///
808/// let x = array![1.0_f64, 2.0, 3.0];
809/// let lse = log_sum_exp_simd::<f64>(&x.view());
810/// // log(e^1 + e^2 + e^3) ≈ 3.407
811/// let expected = (1.0_f64.exp() + 2.0_f64.exp() + 3.0_f64.exp()).ln();
812/// assert!((lse - expected).abs() < 1e-10);
813/// ```
814///
815/// # Use Cases
816/// - Softmax denominator
817/// - Log-probability computations
818/// - Partition function in statistical mechanics
819/// - Evidence lower bound (ELBO) in VAEs
820pub fn log_sum_exp_simd<F>(a: &ArrayView1<F>) -> F
821where
822    F: Float + SimdUnifiedOps,
823{
824    if a.is_empty() {
825        return F::neg_infinity();
826    }
827    F::simd_log_sum_exp(a)
828}
829/// SIMD-accelerated L2 norm (Euclidean norm)
830///
831/// Computes ||x||₂ = sqrt(sum(x²))
832///
833/// # Arguments
834/// * `a` - Input array
835///
836/// # Returns
837/// L2 (Euclidean) norm
838///
839/// # Examples
840/// ```
841/// use scirs2_core::ndarray::array;
842/// use scirs2_core::ndarray_ext::elementwise::norm_simd;
843///
844/// let x = array![3.0_f64, 4.0];
845/// let n = norm_simd::<f64>(&x.view());
846/// // sqrt(9 + 16) = 5
847/// assert!((n - 5.0).abs() < 1e-14);
848/// ```
849///
850/// # Use Cases
851/// - Vector magnitude
852/// - Normalization preprocessing
853/// - Regularization penalty
854/// - Gradient clipping
855pub fn norm_simd<F>(a: &ArrayView1<F>) -> F
856where
857    F: Float + SimdUnifiedOps,
858{
859    if a.is_empty() {
860        return F::zero();
861    }
862    F::simd_norm(a)
863}
864/// SIMD-accelerated L1 norm (Manhattan norm)
865///
866/// Computes ||x||₁ = sum(|x|)
867///
868/// # Arguments
869/// * `a` - Input array
870///
871/// # Returns
872/// L1 (Manhattan) norm
873///
874/// # Examples
875/// ```
876/// use scirs2_core::ndarray::array;
877/// use scirs2_core::ndarray_ext::elementwise::norm_l1_simd;
878///
879/// let x = array![1.0_f64, -2.0, 3.0, -4.0];
880/// let n = norm_l1_simd::<f64>(&x.view());
881/// // |1| + |-2| + |3| + |-4| = 10
882/// assert!((n - 10.0).abs() < 1e-14);
883/// ```
884///
885/// # Use Cases
886/// - Sparse regularization (LASSO)
887/// - Robust statistics
888/// - Compressed sensing
889/// - Feature selection
890pub fn norm_l1_simd<F>(a: &ArrayView1<F>) -> F
891where
892    F: Float + SimdUnifiedOps,
893{
894    if a.is_empty() {
895        return F::zero();
896    }
897    F::simd_norm_l1(a)
898}
899/// SIMD-accelerated L-infinity norm (Chebyshev/max norm)
900///
901/// Computes ||x||∞ = max(|x|)
902///
903/// # Arguments
904/// * `a` - Input array
905///
906/// # Returns
907/// L-infinity (max) norm
908///
909/// # Examples
910/// ```
911/// use scirs2_core::ndarray::array;
912/// use scirs2_core::ndarray_ext::elementwise::norm_linf_simd;
913///
914/// let x = array![1.0_f64, -5.0, 3.0, -2.0];
915/// let n = norm_linf_simd::<f64>(&x.view());
916/// // max(|1|, |-5|, |3|, |-2|) = 5
917/// assert!((n - 5.0).abs() < 1e-14);
918/// ```
919///
920/// # Use Cases
921/// - Gradient clipping by max norm
922/// - Adversarial robustness (L∞ perturbations)
923/// - Convergence criteria
924/// - Worst-case analysis
925pub fn norm_linf_simd<F>(a: &ArrayView1<F>) -> F
926where
927    F: Float + SimdUnifiedOps,
928{
929    if a.is_empty() {
930        return F::zero();
931    }
932    F::simd_norm_linf(a)
933}
934/// SIMD-accelerated Euclidean distance
935///
936/// Computes ||a - b||₂ = sqrt(sum((a - b)²))
937///
938/// # Arguments
939/// * `a` - First vector
940/// * `b` - Second vector
941///
942/// # Returns
943/// Euclidean distance between vectors
944///
945/// # Examples
946/// ```
947/// use scirs2_core::ndarray::array;
948/// use scirs2_core::ndarray_ext::elementwise::distance_euclidean_simd;
949///
950/// let a = array![0.0_f64, 0.0];
951/// let b = array![3.0_f64, 4.0];
952/// let d = distance_euclidean_simd::<f64>(&a.view(), &b.view());
953/// assert!((d - 5.0).abs() < 1e-14);
954/// ```
955///
956/// # Use Cases
957/// - K-means clustering
958/// - Nearest neighbor search
959/// - Physical distance measurement
960/// - Embedding similarity
961pub fn distance_euclidean_simd<F>(a: &ArrayView1<F>, b: &ArrayView1<F>) -> F
962where
963    F: Float + SimdUnifiedOps,
964{
965    if a.is_empty() || b.is_empty() {
966        return F::zero();
967    }
968    F::simd_distance_euclidean(a, b)
969}
970/// SIMD-accelerated Manhattan distance
971///
972/// Computes sum(|a - b|)
973///
974/// # Arguments
975/// * `a` - First vector
976/// * `b` - Second vector
977///
978/// # Returns
979/// Manhattan (L1) distance between vectors
980///
981/// # Examples
982/// ```
983/// use scirs2_core::ndarray::array;
984/// use scirs2_core::ndarray_ext::elementwise::distance_manhattan_simd;
985///
986/// let a = array![1.0_f64, 2.0, 3.0];
987/// let b = array![4.0_f64, 0.0, 3.0];
988/// let d = distance_manhattan_simd::<f64>(&a.view(), &b.view());
989/// // |1-4| + |2-0| + |3-3| = 3 + 2 + 0 = 5
990/// assert!((d - 5.0).abs() < 1e-14);
991/// ```
992///
993/// # Use Cases
994/// - Grid-based path finding
995/// - Robust distance metric
996/// - Taxicab geometry
997/// - Feature comparison
998pub fn distance_manhattan_simd<F>(a: &ArrayView1<F>, b: &ArrayView1<F>) -> F
999where
1000    F: Float + SimdUnifiedOps,
1001{
1002    if a.is_empty() || b.is_empty() {
1003        return F::zero();
1004    }
1005    F::simd_distance_manhattan(a, b)
1006}