;;; Examples of Map, Reduce, Slice, and Concat with Fusion (import scheme (chicken base) (chicken time) srfi-1 fusion-arrays) (define (example-functional-patterns) "Show how the fusion operations enable functional programming patterns" ;; Map-Reduce pattern (print "Map-Reduce Pattern:") (let* ((data (array-range 100 1 1 'f64)) ; 1 to 100 ;; Classic map-reduce: sum of squares (sum-of-squares (array-reduce 'sum (array-map (lambda (x) (* x x)) data))) ;; More complex: sum of even squares (sum-even-squares (array-reduce 'sum (array-map (lambda (x) (if (= (modulo (inexact->exact x) 2) 0) (* x x) 0)) data)))) (print " Data: 1 to 100") (print " Sum of squares: " (compute! sum-of-squares)) (print " Sum of even squares: " (compute! sum-even-squares)) (print " Expected sum of squares: " (/ (* 100 101 201) 6)) ; n(n+1)(2n+1)/6 (print)) ;; Filter-Map-Reduce chain (print "Filter-Map-Reduce Chain:") (let* ((scores (array-from-list '(85.5 92.0 78.5 95.5 88.0 72.0 96.5 83.5 91.0 87.5))) ;; Complex processing: normalize high scores and get average (high-score-average (array-reduce 'mean (array-map (lambda (x) (/ (- x 70.0) 30.0)) ; normalize (array-filter (lambda (x) (>= x 85.0)) scores))))) (print " Scores: " (array->list scores)) (print " Processing: filter(>=85) -> map(normalize) -> mean") (print " High score average (normalized): " (compute! high-score-average)) (print)) ;; Slice and concatenate for windowing (print "Sliding Window with Slice and Concat:") (let* ((signal (array-from-list '(1.0 4.0 2.0 8.0 5.0 7.0 3.0 6.0 9.0 1.0))) (window-size 3) (n (array-size signal)) ;; Create overlapping windows using slice (windows (let loop ((i 0) (result '())) (if (> (+ i window-size) n) (reverse result) (loop (+ i 1) (cons (array-slice signal i (+ i window-size)) result))))) ;; Process each window and concatenate results (window-means (map (lambda (window) (array-reduce 'mean window)) windows)) ;; Combine into single array (smooth-signal (apply array-concat (map (lambda (mean) (array-from-list (list (compute! mean)))) window-means)))) (print " Original signal: " (array->list signal)) (print " Window size: " window-size) (print " Smoothed signal: " (array->list (compute! smooth-signal))) (print)) ;; Complex data transformation pipeline (print "Complex Data Pipeline:") (let* ((raw-data (array-random-normal 1000 100.0 15.0)) ;; Multi-stage processing pipeline (processed-data (array-pipeline raw-data ;; Stage 1: Outlier clipping (array-map* (lambda (x) (max 70.0 (min 130.0 x)))) ;; Stage 2: Take middle 80% (array-slice 100 900) ;; Stage 3: Z-score normalization (uses reduce!) (lambda (arr) (let ((mean (array-reduce 'mean arr)) (std (array-reduce 'std arr))) (array-map (lambda (x) (/ (- x (compute! mean)) (compute! std))) arr))) ;; Stage 4: Apply sigmoid (array-map* (lambda (x) (/ 1.0 (+ 1.0 (exp (- x)))))) ;; Stage 5: Scale to [0, 100] (array-scale 100.0) ))) (print " Raw data: " (array-size raw-data) " samples") (print " Processing: clip -> slice -> normalize -> sigmoid -> scale") (print " Final size: " (array-size processed-data)) (print " Final range: [" (array-min-val (compute! processed-data)) ", " (array-max-val (compute! processed-data)) "]") (print " Final mean: " (array-mean (compute! processed-data))) (print)) ) (define (benchmark-map-reduce) "Benchmark the performance of map, reduce, slice, and concat operations" ;; Map operation performance (print "Map Operation Performance:") (let* ((sizes '(1000 10000 100000 1000000)) (test-func (lambda (x) (* x x x)))) ; Cubic function (for-each (lambda (n) (let* ((data (array-range n 1 1 'f64)) (start (current-process-milliseconds))) (let ((result (compute! (array-map test-func data)))) (let ((end (current-process-milliseconds))) (print " Size " n ": " (- end start) " ms (" (/ n (/ (- end start) 1000.0)) " elements/sec)"))))) sizes) (print)) ;; Reduce operation performance (print "Reduce Operation Performance:") (let ((sizes '(1000 10000 100000 1000000))) (for-each (lambda (n) (let* ((data (array-random-normal n)) (start (current-process-milliseconds))) (let ((mean (compute! (array-reduce 'mean data))) (std (compute! (array-reduce 'std data))) (sum (compute! (array-reduce 'sum data)))) (let ((end (current-process-milliseconds))) (print " Size " n ": " (- end start) " ms (mean=" mean ", std=" std ")"))))) sizes) (print)) ;; Slice operation performance (print "Slice Operation Performance:") (let* ((n 1000000) (data (array-range n 0 1 'f64)) (slice-sizes '(1000 10000 100000 500000))) (for-each (lambda (slice-size) (let ((start (current-process-milliseconds))) (let ((result (compute! (array-slice data 0 slice-size)))) (let ((end (current-process-milliseconds))) (print " Slice " slice-size "/" n ": " (- end start) " ms"))))) slice-sizes) (print)) ;; Concat operation performance (print "Concat Operation Performance:") (let ((array-sizes '((100 100 100) (1000 1000 1000) (10000 10000 10000)))) (for-each (lambda (sizes) (let* ((arrays (map (lambda (size) (array-random-normal size)) sizes)) (start (current-process-milliseconds))) (let ((result (compute! (apply array-concat arrays)))) (let ((end (current-process-milliseconds))) (print " Concat " sizes " -> " (array-size result) ": " (- end start) " ms"))))) array-sizes) (print)) ;; Complex pipeline performance (print "Complex Pipeline Performance:") (let* ((n 100000) (data (array-random-normal n)) (start (current-process-milliseconds))) (let* ((result (array-pipeline data ;; Map: square each element (array-map* (lambda (x) (* x x))) ;; Slice: take middle 80% (array-slice (inexact->exact (* n 0.1)) (inexact->exact (* n 0.9))) ;; Map: apply exponential (array-map* exp) ;; Reduce: get statistics (lambda (arr) (list (array-reduce 'mean arr) (array-reduce 'std arr) (array-reduce 'max arr)))))) (let ((end (current-process-milliseconds))) (print " Pipeline (map->slice->map->reduce) on " n " elements:") (print " Time: " (- end start) " ms") (print " Results: mean=" (compute! (car result)) ", std=" (compute! (cadr result) ) ", max=" (compute! (caddr result))) ))) (print)) (define (example-advanced-map-reduce) "Show advanced usage patterns combining all operations" ;; Data cleaning pipeline (print "Data Cleaning Pipeline:") (let* ((messy-data (array-from-list '(1.0 -999.0 3.0 4.0 -999.0 6.0 7.0 8.0 -999.0 10.0))) (missing-value -999.0) ;; Clean and interpolate (cleaned-data (array-pipeline messy-data ;; Replace missing values with mean of neighbors (lambda (arr) (let ((size (array-size arr))) (array-map (lambda (i) (let ((val (array-ref arr (inexact->exact i)))) (if (= val missing-value) ;; Simple interpolation (/ (+ (if (> i 0) (array-ref arr (- (inexact->exact i) 1)) 0.0) (if (< i (- size 1)) (array-ref arr (+ (inexact->exact i) 1)) 0.0)) 2.0) val))) (array-range size 0 1 'f64)))) ;; Smooth with moving average (array-moving-average 3) ))) (print " Original: " (array->list messy-data)) (print " Cleaned: " (array->list (compute! cleaned-data))) (print)) ;; Feature extraction (print "Feature Extraction from Time Series:") (let* ((time-series (array+ (array-sin (array-scale (array-range 1000 0 0.1 'f64) 0.1)) (array-scale (array-random-normal 1000) 0.1))) ;; Extract multiple features (features (let ((mean-val (array-reduce 'mean time-series)) (std-val (array-reduce 'std time-series)) (min-val (array-reduce 'min time-series)) (max-val (array-reduce 'max time-series)) (trend (array-reduce 'mean (array-diff time-series))) (peaks (array-count (lambda (x) (> x 0.5)) time-series))) `((mean . ,(compute! mean-val)) (std . ,(compute! std-val)) (range . ,(- (compute! max-val) (compute! min-val))) (trend . ,(compute! trend)) (peak-count . ,peaks) (complexity . ,(compute! (array-reduce 'std (array-diff time-series)))))))) (print " Time series length: " (array-size time-series)) (print " Extracted features:") (for-each (lambda (feature) (print " " (car feature) ": " (cdr feature))) features) (print)) ;; Multi-dimensional processing (print "Multi-dimensional Data Processing:") (let* ((n-channels 10) (n-samples 1000) ;; Simulate multi-channel data (channels (map (lambda (ch) (array+ (array-sin (array-scale (array-range n-samples 0 0.01 'f64) (+ 1.0 (* ch 0.1)))) (array-scale (array-random-normal n-samples) 0.05))) (iota n-channels))) ;; Process all channels (processed-channels (map (lambda (channel) (array-pipeline channel ;; High-pass filter (approximate) (lambda (arr) (array- arr (array-moving-average arr 50))) ;; Normalize (lambda (arr) (let ((std (array-reduce 'std arr))) (array-scale arr (/ 1.0 (compute! std))))) ;; Extract envelope (array-abs))) channels)) ;; Combine channels (combined (reduce (lambda (x ax) (array+ x ax)) #f processed-channels)) (final-features (array-moving-average combined 10))) (print " Multi-channel data: " n-channels " channels × " n-samples " samples") (print " Processing: highpass -> normalize -> envelope -> combine -> smooth") (print " Final result size: " (array-size final-features)) (print " Final mean: " (array-mean (compute! final-features))) (print)) ) ;; Main demonstration function (define (run-all-examples) "Run all examples of map/reduce/slice/concat operations" (example-advanced-map-reduce) (example-functional-patterns) (print "\n" (make-string 70 #\=) "\n") (benchmark-map-reduce) (print "\n" (make-string 70 #\=) "\n") ) (run-all-examples)