# Fusion Arrays [![Chicken Scheme](https://img.shields.io/badge/Chicken-Scheme-orange.svg)](https://call-cc.org/) Lazy arrays with fusion in Chicken Scheme. ## Features - **Fusion Support**: Automatic elimination of intermediate arrays - **Push-Pull Evaluation**: Index-by-index computation without materialization - **Type Safety**: Multiple element types (f64, f32, s64, s32, u32, generic) - **Functional API**: Map, reduce, filter, zip operations - **Signal Processing**: FFT, convolution, filtering, correlation - **Pipeline Syntax**: Readable chained operations ## Installation ```bash # Install fusion-arrays chicken-install fusion-arrays ``` Or clone from GitHub: ```bash git clone https://github.com/iraikov/fusion-arrays.git cd fusion-arrays chicken-install . ``` ## Quick Start ```scheme (import fusion-arrays) ;; Create arrays (define x (array-linspace 0 (* 2 3.14159) 1000)) (define noise (array-random-normal 1000 0.0 0.1)) ;; Build lazy computation (no allocation yet!) (define signal (array+ (array-sin (array-scale x 10.0)) (array+ (array-exp (array-scale x -0.1)) noise))) ;; Force computation when needed (compute! signal) ; Returns materialized f64array (array->list signal) ; Force and convert to list ;; Use pipeline syntax for readability (array-pipeline x (array-scale 10.0) (array-sin) (array+ noise)) ``` ## Basic Operations ### Array Creation ```scheme (array-zeros 100) ; 100 zeros (f64) (array-ones 50 'f32) ; 50 ones (f32) (array-range 10 :start 5) ; [5,6,7,8,9,10,11,12,13,14] (array-linspace 0 1 100) ; 100 points from 0 to 1 (array-from-list '(1 2 3)) ; From Scheme list ``` ### Arithmetic ```scheme (array+ a b) (array- a b) (array* a b) (array/ a b) (array-scale a 2.0) (array-negate a) (array-abs a) (array-sqrt a) (array-exp a) (array-log a) (array-sin a) (array-cos a) ``` ### Comparison ```scheme (array> a b) (array< a b) (array= a b) ; Returns 1.0/0.0 (array-and a b) (array-or a b) (array-not a) ``` ### Functional Operations ```scheme (array-map (lambda (x) (* x x)) arr) ; Map (array-reduce 'sum arr) ; Reduction (array-fold (lambda (x acc) (+ x acc)) 0 arr) ; Fold (array-slice arr 10 20) ; Slice (array-filter (lambda (x) (> x 0)) arr) ; Filter (array-zip (lambda (x y) (+ x y)) a b) ; Zip ``` ### Statistical Operations ```scheme (array-sum arr) (array-mean arr) (array-var arr) (array-std arr) (array-min-val arr) (array-max-val arr) (array-moving-average arr 50) ; Moving window (array-moving-std arr 10) ``` ## Signal Processing ### Convolution ```scheme (array-convolve signal kernel 'valid) ; 'valid, 'same, 'full (array-gaussian-filter arr 2.0) ; Gaussian blur (array-correlate arr1 arr2) ; Cross-correlation ``` ### FFT ```scheme ;; Forward FFT of real array (size must be power of 2) (let-values ([(re im) (array-fft real-array)]) ...) ;; Inverse FFT (let-values ([(re im) (array-ifft real-part imag-part)]) ...) ``` ### Integration ```scheme (array-integrate arr 0.01) ; Trapezoidal rule with dx=0.01 ``` ## Pipeline Syntax For more readable chained operations: ```scheme (array-pipeline input (array-scale 2.0) ; multiply by 2 (array-sin) ; take sine (array+ noise) ; add noise (array-filter (> 0)) ; keep positive values (array-mean)) ; compute mean ``` ## Type System | Type | Description | Size | |----------|-----------------------|----------| | `'f64` | Double float | 64-bit | | `'f32` | Single float | 32-bit | | `'s64` | 64-bit signed int | 64-bit | | `'s32` | 32-bit signed int | 32-bit | | `'u32` | 32-bit unsigned int | 32-bit | | `'generic` | Any Scheme value | variable | Type promotion follows standard rules: - Integers - floating point on division - Transcendental functions - floating point - Operations promote to highest type ## Performance Tips 1. **Fusion is lazy** - operations build expression trees 2. **Materialize early** when reusing results 3. **Use pipelines** for complex chains 4. **Prefer typed arrays** over generic for speed ```scheme ;; Good: Build fusion, materialize once (let ((result (compute! expensive-fusion-expression))) (array-mean result) (array-std result)) ;; Bad: Re-computes the fusion expression each time (array-mean expensive-fusion-expression) (array-std expensive-fusion-expression) ``` ## Differences from NumPy | Feature | NumPy | Fusion Arrays | |------------------|----------------------|-----------------------| | Evaluation | Eager | Lazy (by default) | | Broadcasting | Automatic | Manual (same size only) | | Type inference | Implicit | Explicit (type required) | | Reductions | Immediate | Lazy (requires `compute!`) | ## Debugging & Analysis ```scheme (pp-fusion expr) ; Visualize fusion plan (fusion-plan expr) ; Get fusion structure (array-complexity expr) ; Compute expression complexity ``` ## Examples ### Waveform Generation ```scheme (define (generate-wave freq amplitude duration sample-rate) (let ((n (inexact->exact (round (* duration sample-rate)))) (omega (* 2 3.14159 freq))) (array-pipeline (array-linspace 0 duration n) (array-scale omega) (array-sin) (array-scale amplitude)))) ;; Generate 440Hz sine wave, 1 second, 44.1kHz sample rate (compute! (generate-wave 440 0.5 1.0 44100)) ``` ### Data Filtering ```scheme (define (remove-outliers arr threshold) (let ((mean (array-mean arr)) (std (array-std arr))) (array-pipeline arr (array- mean) ; subtract mean (array-abs) ; absolute value (array-scale (/ 1.0 std)) ; normalize by std (array-filter (lambda (x) (< x threshold)))))) ;; Remove values more than 2 standard deviations from mean (remove-outliers data 2.0) ``` ## API Reference See [CHICKEN Scheme Wiki](https://wiki.call-cc.org/) for full documentation. ## Requirements - Chicken Scheme 5.0+ - Dependencies: datatype, matchable, srfi-1, srfi-4 ## License GPL-3 ## Acknowledgments - Inspired by [ acceleration library](https://hackage.haskell.org/package/accelerate) and [NumPy](https://numpy.org/)