1 USING: accessors alien alien.c-types arrays byte-arrays combinators
2 combinators.short-circuit fry kernel macros math math.blas.cblas
3 math.complex math.functions math.order multi-methods qualified
4 sequences sequences.private generalizations ;
8 TUPLE: blas-vector-base data length inc ;
9 TUPLE: float-blas-vector < blas-vector-base ;
10 TUPLE: double-blas-vector < blas-vector-base ;
11 TUPLE: float-complex-blas-vector < blas-vector-base ;
12 TUPLE: double-complex-blas-vector < blas-vector-base ;
14 INSTANCE: float-blas-vector sequence
15 INSTANCE: double-blas-vector sequence
16 INSTANCE: float-complex-blas-vector sequence
17 INSTANCE: double-complex-blas-vector sequence
19 C: <float-blas-vector> float-blas-vector
20 C: <double-blas-vector> double-blas-vector
21 C: <float-complex-blas-vector> float-complex-blas-vector
22 C: <double-complex-blas-vector> double-complex-blas-vector
24 GENERIC: n*V+V! ( alpha x y -- y=alpha*x+y )
25 GENERIC: n*V! ( alpha x -- x=alpha*x )
27 GENERIC: V. ( x y -- x.y )
28 GENERIC: V.conj ( x y -- xconj.y )
29 GENERIC: Vnorm ( x -- norm )
30 GENERIC: Vasum ( x -- sum )
31 GENERIC: Vswap ( x y -- x=y y=x )
33 GENERIC: Viamax ( x -- max-i )
35 GENERIC: element-type ( v -- type )
37 METHOD: element-type { float-blas-vector }
39 METHOD: element-type { double-blas-vector }
41 METHOD: element-type { float-complex-blas-vector }
43 METHOD: element-type { double-complex-blas-vector }
48 GENERIC: (blas-vector-like) ( data length inc exemplar -- vector )
50 METHOD: (blas-vector-like) { object object object float-blas-vector }
51 drop <float-blas-vector> ;
52 METHOD: (blas-vector-like) { object object object double-blas-vector }
53 drop <double-blas-vector> ;
54 METHOD: (blas-vector-like) { object object object float-complex-blas-vector }
55 drop <float-complex-blas-vector> ;
56 METHOD: (blas-vector-like) { object object object double-complex-blas-vector }
57 drop <double-complex-blas-vector> ;
59 : (prepare-copy) ( v element-size -- length v-data v-inc v-dest-data v-dest-inc )
60 [ [ length>> ] [ data>> ] [ inc>> ] tri ] dip
61 4 npick * <byte-array>
64 MACRO: (do-copy) ( copy make-vector -- )
65 '[ over 6 npick , 2dip 1 @ ] ;
67 : (prepare-swap) ( v1 v2 -- length v1-data v1-inc v2-data v2-inc v1 v2 )
69 [ [ length>> ] bi@ min ]
70 [ [ [ data>> ] [ inc>> ] bi ] bi@ ] 2bi
73 : (prepare-axpy) ( n v1 v2 -- length n v1-data v1-inc v2-data v2-inc v2 )
75 [ [ length>> ] bi@ min swap ]
76 [ [ [ data>> ] [ inc>> ] bi ] bi@ ] 2bi
79 : (prepare-scal) ( n v -- length n v-data v-inc v )
80 [ [ length>> swap ] [ data>> ] [ inc>> ] tri ] keep ;
82 : (prepare-dot) ( v1 v2 -- length v1-data v1-inc v2-data v2-inc )
83 [ [ length>> ] bi@ min ]
84 [ [ [ data>> ] [ inc>> ] bi ] bi@ ] 2bi ;
86 : (prepare-nrm2) ( v -- length v1-data v1-inc )
87 [ length>> ] [ data>> ] [ inc>> ] tri ;
89 : (flatten-complex-sequence) ( seq -- seq' )
90 [ [ real-part ] [ imaginary-part ] bi 2array ] map concat ;
92 : (>c-complex) ( complex -- alien )
93 [ real-part ] [ imaginary-part ] bi 2array >c-float-array ;
94 : (>z-complex) ( complex -- alien )
95 [ real-part ] [ imaginary-part ] bi 2array >c-double-array ;
97 : (c-complex>) ( alien -- complex )
98 2 c-float-array> first2 rect> ;
99 : (z-complex>) ( alien -- complex )
100 2 c-double-array> first2 rect> ;
102 : (prepare-nth) ( n v -- n*inc v-data )
103 [ inc>> ] [ data>> ] bi [ * ] dip ;
105 MACRO: (complex-nth) ( nth-quot -- )
111 : (c-complex-nth) ( n alien -- complex )
112 [ float-nth ] (complex-nth) ;
113 : (z-complex-nth) ( n alien -- complex )
114 [ double-nth ] (complex-nth) ;
116 MACRO: (set-complex-nth) ( set-nth-quot -- )
119 [ [ real-part ] [ imaginary-part ] bi ]
126 : (set-c-complex-nth) ( complex n alien -- )
127 [ set-float-nth ] (set-complex-nth) ;
128 : (set-z-complex-nth) ( complex n alien -- )
129 [ set-double-nth ] (set-complex-nth) ;
133 : <zero-vector> ( exemplar -- zero )
134 [ element-type <c-object> ]
136 [ (blas-vector-like) ] tri ;
138 : <empty-vector> ( length exemplar -- vector )
139 [ element-type <c-array> ]
143 syntax:M: blas-vector-base length
146 syntax:M: float-blas-vector nth-unsafe
147 (prepare-nth) float-nth ;
148 syntax:M: float-blas-vector set-nth-unsafe
149 (prepare-nth) set-float-nth ;
151 syntax:M: double-blas-vector nth-unsafe
152 (prepare-nth) double-nth ;
153 syntax:M: double-blas-vector set-nth-unsafe
154 (prepare-nth) set-double-nth ;
156 syntax:M: float-complex-blas-vector nth-unsafe
157 (prepare-nth) (c-complex-nth) ;
158 syntax:M: float-complex-blas-vector set-nth-unsafe
159 (prepare-nth) (set-c-complex-nth) ;
161 syntax:M: double-complex-blas-vector nth-unsafe
162 (prepare-nth) (z-complex-nth) ;
163 syntax:M: double-complex-blas-vector set-nth-unsafe
164 (prepare-nth) (set-z-complex-nth) ;
166 syntax:M: blas-vector-base equal?
172 : >float-blas-vector ( seq -- v )
173 [ >c-float-array ] [ length ] bi 1 <float-blas-vector> ;
174 : >double-blas-vector ( seq -- v )
175 [ >c-double-array ] [ length ] bi 1 <double-blas-vector> ;
176 : >float-complex-blas-vector ( seq -- v )
177 [ (flatten-complex-sequence) >c-float-array ] [ length ] bi
178 1 <float-complex-blas-vector> ;
179 : >double-complex-blas-vector ( seq -- v )
180 [ (flatten-complex-sequence) >c-double-array ] [ length ] bi
181 1 <double-complex-blas-vector> ;
183 syntax:M: float-blas-vector clone
184 "float" heap-size (prepare-copy)
185 [ cblas_scopy ] [ <float-blas-vector> ] (do-copy) ;
186 syntax:M: double-blas-vector clone
187 "double" heap-size (prepare-copy)
188 [ cblas_dcopy ] [ <double-blas-vector> ] (do-copy) ;
189 syntax:M: float-complex-blas-vector clone
190 "CBLAS_C" heap-size (prepare-copy)
191 [ cblas_ccopy ] [ <float-complex-blas-vector> ] (do-copy) ;
192 syntax:M: double-complex-blas-vector clone
193 "CBLAS_Z" heap-size (prepare-copy)
194 [ cblas_zcopy ] [ <double-complex-blas-vector> ] (do-copy) ;
196 METHOD: Vswap { float-blas-vector float-blas-vector }
197 (prepare-swap) [ cblas_sswap ] 2dip ;
198 METHOD: Vswap { double-blas-vector double-blas-vector }
199 (prepare-swap) [ cblas_dswap ] 2dip ;
200 METHOD: Vswap { float-complex-blas-vector float-complex-blas-vector }
201 (prepare-swap) [ cblas_cswap ] 2dip ;
202 METHOD: Vswap { double-complex-blas-vector double-complex-blas-vector }
203 (prepare-swap) [ cblas_zswap ] 2dip ;
205 METHOD: n*V+V! { real float-blas-vector float-blas-vector }
206 (prepare-axpy) [ cblas_saxpy ] dip ;
207 METHOD: n*V+V! { real double-blas-vector double-blas-vector }
208 (prepare-axpy) [ cblas_daxpy ] dip ;
209 METHOD: n*V+V! { number float-complex-blas-vector float-complex-blas-vector }
210 [ (>c-complex) ] 2dip
211 (prepare-axpy) [ cblas_caxpy ] dip ;
212 METHOD: n*V+V! { number double-complex-blas-vector double-complex-blas-vector }
213 [ (>z-complex) ] 2dip
214 (prepare-axpy) [ cblas_zaxpy ] dip ;
216 METHOD: n*V! { real float-blas-vector }
217 (prepare-scal) [ cblas_sscal ] dip ;
218 METHOD: n*V! { real double-blas-vector }
219 (prepare-scal) [ cblas_dscal ] dip ;
220 METHOD: n*V! { number float-complex-blas-vector }
222 (prepare-scal) [ cblas_cscal ] dip ;
223 METHOD: n*V! { number double-complex-blas-vector }
225 (prepare-scal) [ cblas_zscal ] dip ;
227 : n*V+V ( alpha x y -- alpha*x+y ) clone n*V+V! ; inline
228 : n*V ( alpha x -- alpha*x ) clone n*V! ; inline
231 1.0 -rot n*V+V ; inline
233 -1.0 spin n*V+V ; inline
236 -1.0 swap n*V ; inline
238 : V*n ( x alpha -- x*alpha )
240 : V/n ( x alpha -- x/alpha )
241 recip swap n*V ; inline
243 METHOD: V. { float-blas-vector float-blas-vector }
244 (prepare-dot) cblas_sdot ;
245 METHOD: V. { double-blas-vector double-blas-vector }
246 (prepare-dot) cblas_ddot ;
247 METHOD: V. { float-complex-blas-vector float-complex-blas-vector }
249 "CBLAS_C" <c-object> [ cblas_cdotu_sub ] keep (c-complex>) ;
250 METHOD: V. { double-complex-blas-vector double-complex-blas-vector }
252 "CBLAS_Z" <c-object> [ cblas_zdotu_sub ] keep (z-complex>) ;
254 METHOD: V.conj { float-blas-vector float-blas-vector }
255 (prepare-dot) cblas_sdot ;
256 METHOD: V.conj { double-blas-vector double-blas-vector }
257 (prepare-dot) cblas_ddot ;
258 METHOD: V.conj { float-complex-blas-vector float-complex-blas-vector }
260 "CBLAS_C" <c-object> [ cblas_cdotc_sub ] keep (c-complex>) ;
261 METHOD: V.conj { double-complex-blas-vector double-complex-blas-vector }
263 "CBLAS_Z" <c-object> [ cblas_zdotc_sub ] keep (z-complex>) ;
265 METHOD: Vnorm { float-blas-vector }
266 (prepare-nrm2) cblas_snrm2 ;
267 METHOD: Vnorm { double-blas-vector }
268 (prepare-nrm2) cblas_dnrm2 ;
269 METHOD: Vnorm { float-complex-blas-vector }
270 (prepare-nrm2) cblas_scnrm2 ;
271 METHOD: Vnorm { double-complex-blas-vector }
272 (prepare-nrm2) cblas_dznrm2 ;
274 METHOD: Vasum { float-blas-vector }
275 (prepare-nrm2) cblas_sasum ;
276 METHOD: Vasum { double-blas-vector }
277 (prepare-nrm2) cblas_dasum ;
278 METHOD: Vasum { float-complex-blas-vector }
279 (prepare-nrm2) cblas_scasum ;
280 METHOD: Vasum { double-complex-blas-vector }
281 (prepare-nrm2) cblas_dzasum ;
283 METHOD: Viamax { float-blas-vector }
284 (prepare-nrm2) cblas_isamax ;
285 METHOD: Viamax { double-blas-vector }
286 (prepare-nrm2) cblas_idamax ;
287 METHOD: Viamax { float-complex-blas-vector }
288 (prepare-nrm2) cblas_icamax ;
289 METHOD: Viamax { double-complex-blas-vector }
290 (prepare-nrm2) cblas_izamax ;
293 [ Viamax ] keep nth ; inline
295 : Vsub ( v start length -- sub )
298 nip [ inc>> ] [ element-type heap-size ] [ data>> ] tri
299 [ * * ] dip <displaced-alien>
300 ] [ swap 2nip ] [ 2nip inc>> ] 3tri
301 ] keep (blas-vector-like) ;