-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathplplot-utils.scm
More file actions
181 lines (147 loc) · 5.18 KB
/
plplot-utils.scm
File metadata and controls
181 lines (147 loc) · 5.18 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
;;; plot-utils.scm
;;; Utility functions for PLplot in SIOD-TR
;;; These work with SIOD's limitations (no named-let, etc.)
;;; Map function over list
(define (map f lst)
(if (null? lst)
'()
(cons (f (car lst)) (map f (cdr lst)))))
;;; Filter list by predicate
(define (filter pred lst)
(cond ((null? lst) '())
((pred (car lst))
(cons (car lst) (filter pred (cdr lst))))
(else (filter pred (cdr lst)))))
;;; Reduce/fold left
(define (foldl f acc lst)
(if (null? lst)
acc
(foldl f (f acc (car lst)) (cdr lst))))
;;; ============================================
;;; Range Generation
;;; ============================================
;;; Simple recursive range - builds list forward
(define (range start end step)
(if (> start end)
'()
(cons start (range (+ start step) end step))))
;;; Alternative: range with helper (uses internal define)
(define (range-helper start end step)
(define (helper current acc)
(if (> current end)
(reverse acc)
(helper (+ current step) (cons current acc))))
(helper start '()))
;;; Integer range: (irange 0 10) => (0 1 2 3 4 5 6 7 8 9 10)
(define (irange start end)
(range start end 1))
;;; ============================================
;;; List Utilities
;;; ============================================
;;; Map a function returning multiple values to separate lists
(define (map-multi f lst)
(if (null? lst)
'(() ())
(let* ((result (f (car lst)))
(rest (map-multi f (cdr lst))))
(list (cons (car result) (car rest))
(cons (cadr result) (cadr rest))))))
;;; Zip two lists together: (zip '(1 2 3) '(4 5 6)) => ((1 4) (2 5) (3 6))
(define (zip xs ys)
(if (or (null? xs) (null? ys))
'()
(cons (list (car xs) (car ys))
(zip (cdr xs) (cdr ys)))))
;;; ============================================
;;; Mathematical Utilities
;;; ============================================
;;; Linear interpolation
(define (lerp a b t)
(+ a (* t (- b a))))
;;; Clamp value between min and max
(define (clamp x min-val max-val)
(cond ((< x min-val) min-val)
((> x max-val) max-val)
(else x)))
;;; Map value from one range to another
(define (map-range value in-min in-max out-min out-max)
(+ out-min
(* (- out-max out-min)
(/ (- value in-min) (- in-max in-min)))))
;;; ============================================
;;; 2D Grid Generation
;;; ============================================
;;; Create 2D grid of values for surface plots
;;; func takes (x y) and returns z value
(define (make-grid x-min x-max nx y-min y-max ny func)
(define dx (/ (- x-max x-min) (- nx 1)))
(define dy (/ (- y-max y-min) (- ny 1)))
(define (make-row y-index)
(define y (+ y-min (* y-index dy)))
(define (make-cell x-index)
(define x (+ x-min (* x-index dx)))
(func x y))
(map make-cell (irange 0 (- nx 1))))
(map make-row (irange 0 (- ny 1))))
;;; ============================================
;;; Common Mathematical Functions
;;; ============================================
;;; Gaussian function
(define (gaussian x mean stddev)
(let ((z (/ (- x mean) stddev)))
(* (/ 1.0 (* stddev (sqrt (* 2.0 3.14159))))
(exp (* -0.5 z z)))))
;;; Sigmoid function
(define (sigmoid x)
(/ 1.0 (+ 1.0 (exp (- x)))))
;;; ============================================
;;; Color Utilities
;;; ============================================
;;; Convert HSV to RGB (returns list of (r g b) values 0-255)
(define (hsv->rgb h s v)
(let* ((c (* v s))
(h-prime (/ h 60.0))
(x (* c (- 1.0 (abs (- (modulo h-prime 2.0) 1.0)))))
(m (- v c))
(rgb-prime
(cond ((< h-prime 1) (list c x 0.0))
((< h-prime 2) (list x c 0.0))
((< h-prime 3) (list 0.0 c x))
((< h-prime 4) (list 0.0 x c))
((< h-prime 5) (list x 0.0 c))
(else (list c 0.0 x)))))
(map (lambda (val) (inexact->exact (truncate (* 255 (+ val m)))))
rgb-prime)))
;;; ============================================
;;; Quick Plotting Helpers
;;; ============================================
;;; Quick line plot to PDF
(define (quick-plot filename x-data y-data title)
(plot-device "pdf")
(plot-output filename)
(plot-init)
(let ((x-min (apply min x-data))
(x-max (apply max x-data))
(y-min (apply min y-data))
(y-max (apply max y-data)))
(plot-env x-min x-max y-min y-max)
(plot-labels "X" "Y" title)
(plot-line x-data y-data))
(plot-end))
;;; Quick function plot - plots f(x) over range
(define (plot-function f x-min x-max filename title)
(let* ((x-vals (range x-min x-max (/ (- x-max x-min) 100.0)))
(y-vals (map f x-vals)))
(quick-plot filename x-vals y-vals title)))
;;; ============================================
;;; Example Usage
;;; ============================================
;;; Plot sine wave:
;;; (plot-function sin 0.0 6.28 "sine.pdf" "Sine Wave")
;;; Create 2D grid:
;;; (define grid (make-grid -1.0 1.0 10 -1.0 1.0 10
;;; (lambda (x y) (+ (* x x) (* y y)))))
;;; Generate range:
;;; (define x (range 0.0 10.0 0.5))
(display "plot-utils.scm loaded")
(newline)