35 ! |
35 ! |
36 |
36 |
37 documentation |
37 documentation |
38 " |
38 " |
39 FloatArrays store floats (and nothing else). |
39 FloatArrays store floats (and nothing else). |
|
40 They have been added to support heavy duty number crunching and |
|
41 data exchange with openGL frameworks and other mass data libraries. |
40 See documentation in DoubleArray for more information. |
42 See documentation in DoubleArray for more information. |
41 |
43 |
42 [memory requirements:] |
44 [memory requirements:] |
43 OBJ-HEADER + (size * float-size) |
45 OBJ-HEADER + (size * float-size) |
44 |
46 |
45 [See also:] |
47 [See also:] |
46 DoubleArray Array |
48 DoubleArray Array |
47 |
49 |
48 [author:] |
50 [author:] |
49 Claus Gittinger |
51 Claus Gittinger |
50 " |
52 " |
51 ! ! |
53 ! ! |
52 |
54 |
53 |
55 |
54 |
56 |
55 !FloatArray class methodsFor:'queries'! |
57 !FloatArray class methodsFor:'queries'! |
56 |
58 |
57 elementByteSize |
59 elementByteSize |
|
60 "for bit-like containers, return the number of bytes stored per element. |
|
61 Here, 4 is returned" |
|
62 |
58 ^ 4 |
63 ^ 4 |
59 |
64 |
60 "Created: / 15-09-2011 / 14:12:39 / cg" |
65 "Created: / 15-09-2011 / 14:12:39 / cg" |
61 ! ! |
66 ! ! |
62 |
67 |
63 |
|
64 !FloatArray methodsFor:'arithmetic'! |
|
65 |
|
66 * anObject |
|
67 "return the product of the receiver and the argument. |
|
68 The argument may either be a scalar or another vector" |
|
69 |
|
70 ^ self clone *= anObject |
|
71 |
|
72 " |
|
73 #(1 2 3 4) asFloatArray * 3 |
|
74 #(1 2 3 4) asFloatArray * #(1 2 3 4) asFloatArray |
|
75 " |
|
76 ! |
|
77 |
|
78 + anObject |
|
79 "return the sum of the receiver and the argument. |
|
80 The argument may either be a scalar or another vector" |
|
81 |
|
82 ^ self clone += anObject |
|
83 |
|
84 " |
|
85 #(1 2 3 4) asFloatArray + 3 |
|
86 #(1 2 3 4) asFloatArray + #(1 2 3 4) asFloatArray |
|
87 " |
|
88 ! |
|
89 |
|
90 - anObject |
|
91 "return the difference of the receiver and the argument. |
|
92 The argument may either be a scalar or another vector" |
|
93 |
|
94 ^ self clone -= anObject |
|
95 |
|
96 " |
|
97 #(1 2 3 4) asFloatArray - 3 |
|
98 #(1 2 3 4) asFloatArray - #(1 2 3 4) asFloatArray |
|
99 " |
|
100 |
|
101 "Created: / 30-05-2007 / 17:41:46 / cg" |
|
102 ! |
|
103 |
|
104 / anObject |
|
105 "return the division of the receiver and the argument. |
|
106 The argument may either be a scalar or another vector" |
|
107 |
|
108 ^ self clone /= anObject |
|
109 |
|
110 " |
|
111 #(1 2 3 4) asFloatArray / 3 |
|
112 #(1 2 3 4) asFloatArray / #(1 2 3 4) asFloatArray |
|
113 " |
|
114 |
|
115 "Created: / 30-05-2007 / 17:46:05 / cg" |
|
116 ! |
|
117 |
|
118 abs |
|
119 ^ self clone primAbs |
|
120 |
|
121 "Created: / 30-05-2007 / 17:47:50 / cg" |
|
122 ! |
|
123 |
|
124 negated |
|
125 ^ self clone primNegated |
|
126 |
|
127 "Modified: / 30-05-2007 / 17:51:47 / cg" |
|
128 ! |
|
129 |
|
130 primAbs |
|
131 "destructive absolute value of each element" |
|
132 |
|
133 %{ |
|
134 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
135 INT _sz = __floatArraySize(self); |
|
136 INT i; |
|
137 float *_p = __FloatArrayInstPtr(self)->f_element; |
|
138 |
|
139 /* how about inline-mmx-asm for this ... */ |
|
140 for (i=0; i<_sz; i++) { |
|
141 float f = _p[i]; |
|
142 |
|
143 if (f < 0) { |
|
144 _p[i] = -f; |
|
145 } |
|
146 } |
|
147 RETURN (self); |
|
148 } |
|
149 %}. |
|
150 1 to: self size do:[:i| self at: i put: (self at: i) abs]. |
|
151 |
|
152 " |
|
153 |f| |
|
154 |
|
155 f := FloatArray withAll:#(-1 2 -3 4 -5). |
|
156 f abs. |
|
157 f |
|
158 " |
|
159 |
|
160 "Created: / 30-05-2007 / 17:50:17 / cg" |
|
161 ! |
|
162 |
|
163 primAddArray: floatArray |
|
164 "add the vector argument into the receiver (destructive). |
|
165 The argument must be another vector" |
|
166 |
|
167 %{ |
|
168 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
|
169 && __isFloats(floatArray) |
|
170 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
|
171 INT _sz1 = __floatArraySize(self); |
|
172 INT _sz2 = __floatArraySize(floatArray); |
|
173 INT i; |
|
174 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
175 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
|
176 |
|
177 if (_sz2 >= _sz1) { |
|
178 /* how about inline-mmx-asm for this ... */ |
|
179 for (i=0; i<_sz1; i++) { |
|
180 _p1[i] += _p2[i]; |
|
181 } |
|
182 } |
|
183 RETURN (self); |
|
184 } |
|
185 %}. |
|
186 1 to: self size do:[:i| self at: i put: (self at: i) + (floatArray at: i)]. |
|
187 |
|
188 " |
|
189 |f1 f2| |
|
190 |
|
191 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
192 f2 := FloatArray withAll:#(2 2 2 3 3). |
|
193 f1 += f2. |
|
194 f1 |
|
195 " |
|
196 ! |
|
197 |
|
198 primAddScalar: aScalar |
|
199 "add the scalar argument into the receiver (destructive)." |
|
200 |
|
201 %{ |
|
202 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
203 INT _sz1 = __floatArraySize(self); |
|
204 INT i; |
|
205 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
206 float v; |
|
207 |
|
208 if (__isFloat(aScalar)) { |
|
209 v = (float)(__floatVal(aScalar)); |
|
210 } else if (__isShortFloat(aScalar)) { |
|
211 v = __shortFloatVal(aScalar); |
|
212 } else if (__isSmallInteger(aScalar)) { |
|
213 v = (float)(__intVal(aScalar)); |
|
214 } else |
|
215 goto badArg; |
|
216 |
|
217 /* how about inline-mmx-asm for this ... */ |
|
218 for (i=0; i<_sz1; i++) { |
|
219 _p1[i] += v; |
|
220 } |
|
221 RETURN (self); |
|
222 } |
|
223 badArg: ; |
|
224 %}. |
|
225 1 to: self size do:[:i| self at: i put: (self at: i) + aScalar]. |
|
226 |
|
227 " |
|
228 |f1 f2| |
|
229 |
|
230 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
231 f1 += 2.0. |
|
232 Transcript showCR:f1. |
|
233 f1 += 2.0 asShortFloat. |
|
234 Transcript showCR:f1. |
|
235 f1 += 2. |
|
236 Transcript showCR:f1. |
|
237 " |
|
238 ! |
|
239 |
|
240 primDivArray: floatArray |
|
241 "divide the vector argument into the receiver (destructive). |
|
242 The argument must be another vector" |
|
243 |
|
244 %{ |
|
245 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
|
246 && __isFloats(floatArray) |
|
247 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
|
248 INT _sz1 = __floatArraySize(self); |
|
249 INT _sz2 = __floatArraySize(floatArray); |
|
250 INT i; |
|
251 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
252 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
|
253 |
|
254 if (_sz2 >= _sz1) { |
|
255 /* how about inline-mmx-asm for this ... */ |
|
256 for (i=0; i<_sz1; i++) { |
|
257 _p1[i] /= _p2[i]; |
|
258 } |
|
259 } |
|
260 RETURN (self); |
|
261 } |
|
262 %}. |
|
263 1 to: self size do:[:i| self at: i put: (self at: i) / (floatArray at: i)]. |
|
264 |
|
265 " |
|
266 |f1 f2| |
|
267 |
|
268 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
269 f2 := FloatArray withAll:#(2 2 2 3 3). |
|
270 f1 /= f2. |
|
271 f1 |
|
272 " |
|
273 |
|
274 "Modified: / 29-05-2007 / 16:01:34 / cg" |
|
275 ! |
|
276 |
|
277 primDivScalar: aScalar |
|
278 "divide the scalar argument into the receiver (destructive)." |
|
279 |
|
280 %{ |
|
281 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
282 INT _sz1 = __floatArraySize(self); |
|
283 INT i; |
|
284 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
285 float v; |
|
286 |
|
287 if (__isFloat(aScalar)) { |
|
288 v = (float)(__floatVal(aScalar)); |
|
289 } else if (__isShortFloat(aScalar)) { |
|
290 v = __shortFloatVal(aScalar); |
|
291 } else if (__isSmallInteger(aScalar)) { |
|
292 v = (float)(__intVal(aScalar)); |
|
293 } else |
|
294 goto badArg; |
|
295 |
|
296 /* how about inline-mmx-asm for this ... */ |
|
297 for (i=0; i<_sz1; i++) { |
|
298 _p1[i] /= v; |
|
299 } |
|
300 RETURN (self); |
|
301 } |
|
302 badArg: ; |
|
303 %}. |
|
304 1 to: self size do:[:i| self at: i put: (self at: i) / aScalar]. |
|
305 |
|
306 " |
|
307 |f1 f2| |
|
308 |
|
309 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
310 f1 /= 2.0. |
|
311 Transcript showCR:f1. |
|
312 f1 /= 2.0 asShortFloat. |
|
313 Transcript showCR:f1. |
|
314 f1 /= 2. |
|
315 Transcript showCR:f1. |
|
316 " |
|
317 |
|
318 "Modified: / 29-05-2007 / 16:01:39 / cg" |
|
319 ! |
|
320 |
|
321 primMulArray: floatArray |
|
322 "multiply the vector argument into the receiver (destructive). |
|
323 The argument must be another vector" |
|
324 |
|
325 %{ |
|
326 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
|
327 && __isFloats(floatArray) |
|
328 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
|
329 INT _sz1 = __floatArraySize(self); |
|
330 INT _sz2 = __floatArraySize(floatArray); |
|
331 INT i; |
|
332 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
333 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
|
334 |
|
335 if (_sz2 >= _sz1) { |
|
336 /* how about inline-mmx-asm for this ... */ |
|
337 for (i=0; i<_sz1; i++) { |
|
338 _p1[i] *= _p2[i]; |
|
339 } |
|
340 } |
|
341 RETURN (self); |
|
342 } |
|
343 %}. |
|
344 1 to: self size do:[:i| self at: i put: (self at: i) * (floatArray at: i)]. |
|
345 |
|
346 " |
|
347 |f1 f2| |
|
348 |
|
349 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
350 f2 := FloatArray withAll:#(2 2 2 3 3). |
|
351 f1 *= f2. |
|
352 f1 |
|
353 " |
|
354 ! |
|
355 |
|
356 primMulScalar: aScalar |
|
357 "multiply the scalar argument into the receiver (destructive)." |
|
358 |
|
359 %{ |
|
360 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
361 INT _sz1 = __floatArraySize(self); |
|
362 INT i; |
|
363 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
364 float v; |
|
365 |
|
366 if (__isFloat(aScalar)) { |
|
367 v = (float)(__floatVal(aScalar)); |
|
368 } else if (__isShortFloat(aScalar)) { |
|
369 v = __shortFloatVal(aScalar); |
|
370 } else if (__isSmallInteger(aScalar)) { |
|
371 v = (float)(__intVal(aScalar)); |
|
372 } else |
|
373 goto badArg; |
|
374 |
|
375 /* how about inline-mmx-asm for this ... */ |
|
376 for (i=0; i<_sz1; i++) { |
|
377 _p1[i] *= v; |
|
378 } |
|
379 RETURN (self); |
|
380 } |
|
381 badArg: ; |
|
382 %}. |
|
383 1 to: self size do:[:i| self at: i put: (self at: i) * aScalar]. |
|
384 |
|
385 " |
|
386 |f1 f2| |
|
387 |
|
388 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
389 f1 *= 2.0. |
|
390 Transcript showCR:f1. |
|
391 f1 *= 2.0 asShortFloat. |
|
392 Transcript showCR:f1. |
|
393 f1 *= 2. |
|
394 Transcript showCR:f1. |
|
395 " |
|
396 ! |
|
397 |
|
398 primNegated |
|
399 "destructive negative value of each element" |
|
400 |
|
401 %{ |
|
402 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
403 INT _sz = __floatArraySize(self); |
|
404 INT i; |
|
405 float *_p = __FloatArrayInstPtr(self)->f_element; |
|
406 |
|
407 /* how about inline-mmx-asm for this ... */ |
|
408 for (i=0; i<_sz; i++) { |
|
409 float f = _p[i]; |
|
410 |
|
411 _p[i] = -f; |
|
412 } |
|
413 RETURN (self); |
|
414 } |
|
415 %}. |
|
416 1 to: self size do:[:i| self at: i put: (self at: i) negated]. |
|
417 |
|
418 " |
|
419 |f| |
|
420 |
|
421 f := FloatArray withAll:#(-1 2 -3 4 -5). |
|
422 f negated. |
|
423 f |
|
424 " |
|
425 |
|
426 "Created: / 30-05-2007 / 17:51:29 / cg" |
|
427 ! |
|
428 |
|
429 primSubtractArray: floatArray |
|
430 "subtract the vector argument from the receiver (destructive). |
|
431 The argument must be another vector" |
|
432 |
|
433 %{ |
|
434 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
|
435 && __isFloats(floatArray) |
|
436 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
|
437 INT _sz1 = __floatArraySize(self); |
|
438 INT _sz2 = __floatArraySize(floatArray); |
|
439 INT i; |
|
440 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
441 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
|
442 |
|
443 if (_sz2 >= _sz1) { |
|
444 /* how about inline-mmx-asm for this ... */ |
|
445 for (i=0; i<_sz1; i++) { |
|
446 _p1[i] -= _p2[i]; |
|
447 } |
|
448 } |
|
449 RETURN (self); |
|
450 } |
|
451 %}. |
|
452 1 to: self size do:[:i| self at: i put: (self at: i) - (floatArray at: i)]. |
|
453 |
|
454 " |
|
455 |f1 f2| |
|
456 |
|
457 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
458 f2 := FloatArray withAll:#(2 2 2 3 3). |
|
459 f1 -= f2. |
|
460 f1 |
|
461 " |
|
462 |
|
463 "Created: / 30-05-2007 / 17:42:41 / cg" |
|
464 ! |
|
465 |
|
466 primSubtractScalar: aScalar |
|
467 "subtract the scalar argument from the receiver (destructive)." |
|
468 |
|
469 %{ |
|
470 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
471 INT _sz1 = __floatArraySize(self); |
|
472 INT i; |
|
473 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
474 float v; |
|
475 |
|
476 if (__isFloat(aScalar)) { |
|
477 v = (float)(__floatVal(aScalar)); |
|
478 } else if (__isShortFloat(aScalar)) { |
|
479 v = __shortFloatVal(aScalar); |
|
480 } else if (__isSmallInteger(aScalar)) { |
|
481 v = (float)(__intVal(aScalar)); |
|
482 } else |
|
483 goto badArg; |
|
484 |
|
485 /* how about inline-mmx-asm for this ... */ |
|
486 for (i=0; i<_sz1; i++) { |
|
487 _p1[i] -= v; |
|
488 } |
|
489 RETURN (self); |
|
490 } |
|
491 badArg: ; |
|
492 %}. |
|
493 1 to: self size do:[:i| self at: i put: (self at: i) - aScalar]. |
|
494 |
|
495 " |
|
496 |f1 f2| |
|
497 |
|
498 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
499 f1 -= 2.0. |
|
500 Transcript showCR:f1. |
|
501 f1 -= 2.0 asShortFloat. |
|
502 Transcript showCR:f1. |
|
503 f1 -= 2. |
|
504 Transcript showCR:f1. |
|
505 " |
|
506 |
|
507 "Created: / 30-05-2007 / 17:43:06 / cg" |
|
508 ! ! |
|
509 |
|
510 !FloatArray methodsFor:'arithmetic destructive'! |
|
511 |
|
512 *= anObject |
|
513 "multiply the argument into the receiver (destructive). |
|
514 The argument may either be a scalar or another vector" |
|
515 |
|
516 ^ anObject isNumber |
|
517 ifTrue:[self primMulScalar: anObject asFloat] |
|
518 ifFalse:[self primMulArray: anObject] |
|
519 |
|
520 " |
|
521 |f| |
|
522 |
|
523 f := #(1 2 3 4) asFloatArray. |
|
524 f *= 3. |
|
525 f |
|
526 " |
|
527 " |
|
528 |f| |
|
529 |
|
530 f := #(1 2 3 4) asFloatArray. |
|
531 f *= #(1 2 3 4) asFloatArray. |
|
532 f |
|
533 " |
|
534 ! |
|
535 |
|
536 += anObject |
|
537 "add the argument into the receiver (destructive). |
|
538 The argument may either be a scalar or another vector" |
|
539 |
|
540 ^ anObject isNumber |
|
541 ifTrue:[self primAddScalar: anObject asFloat] |
|
542 ifFalse:[self primAddArray: anObject] |
|
543 |
|
544 " |
|
545 |f| |
|
546 |
|
547 f := #(1 2 3 4) asFloatArray. |
|
548 f += 3. |
|
549 f |
|
550 " |
|
551 " |
|
552 |f| |
|
553 |
|
554 f := #(1 2 3 4) asFloatArray. |
|
555 f += #(1 2 3 4) asFloatArray. |
|
556 f |
|
557 " |
|
558 ! |
|
559 |
|
560 -= anObject |
|
561 "subtract the argument from the receiver (destructive). |
|
562 The argument may either be a scalar or another vector" |
|
563 |
|
564 ^ anObject isNumber |
|
565 ifTrue:[self primSubtractScalar: anObject asFloat] |
|
566 ifFalse:[self primSubtractArray: anObject] |
|
567 |
|
568 " |
|
569 |f| |
|
570 |
|
571 f := #(1 2 3 4) asFloatArray. |
|
572 f -= 3. |
|
573 f |
|
574 " |
|
575 " |
|
576 |f| |
|
577 |
|
578 f := #(1 2 3 4) asFloatArray. |
|
579 f += #(1 2 3 4) asFloatArray. |
|
580 f |
|
581 " |
|
582 |
|
583 "Created: / 30-05-2007 / 17:42:13 / cg" |
|
584 ! |
|
585 |
|
586 /= anObject |
|
587 "divide the argument into the receiver (destructive). |
|
588 The argument may either be a scalar or another vector" |
|
589 |
|
590 ^ anObject isNumber |
|
591 ifTrue:[self primDivScalar: anObject asFloat] |
|
592 ifFalse:[self primDivArray: anObject] |
|
593 |
|
594 "Modified: / 30-05-2007 / 17:45:46 / cg" |
|
595 ! ! |
|
596 |
68 |
597 !FloatArray methodsFor:'copying'! |
69 !FloatArray methodsFor:'copying'! |
598 |
70 |
599 clone |
71 clone |
600 "return a copy of the receiver" |
72 "return a copy of the receiver" |
708 f2 := #(10 9 8 7 6) asFloatArray. |
180 f2 := #(10 9 8 7 6) asFloatArray. |
709 f1 replaceFrom:1 to:3 with:f2 startingAt:3 |
181 f1 replaceFrom:1 to:3 with:f2 startingAt:3 |
710 " |
182 " |
711 ! ! |
183 ! ! |
712 |
184 |
|
185 !FloatArray methodsFor:'destructive arithmetic support'! |
|
186 |
|
187 primAbs |
|
188 "destructive absolute value of each element" |
|
189 |
|
190 %{ |
|
191 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
192 INT _sz = __floatArraySize(self); |
|
193 INT i; |
|
194 float *_p = __FloatArrayInstPtr(self)->f_element; |
|
195 float prev_p; |
|
196 |
|
197 if (_sz > 0) { |
|
198 /* how about inline-mmx-asm for this ... */ |
|
199 prev_p = _p[0]; |
|
200 for (i=1; i<_sz; i++) { |
|
201 float next_p = _p[i]; |
|
202 |
|
203 if (prev_p < 0) { |
|
204 _p[i-1] = -prev_p; |
|
205 } |
|
206 prev_p = next_p; |
|
207 } |
|
208 if (prev_p < 0) { |
|
209 _p[i-1] = -prev_p; |
|
210 } |
|
211 } |
|
212 RETURN (self); |
|
213 } |
|
214 %}. |
|
215 super primAbs |
|
216 |
|
217 " |
|
218 |f| |
|
219 |
|
220 f := FloatArray withAll:#(-1 2 -3 4 -5). |
|
221 f abs. |
|
222 f |
|
223 " |
|
224 |
|
225 "Created: / 30-05-2007 / 17:50:17 / cg" |
|
226 ! |
|
227 |
|
228 primAddArray: floatArray |
|
229 "add the vector argument into the receiver (destructive). |
|
230 The argument must be another vector" |
|
231 |
|
232 %{ |
|
233 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
|
234 && __isFloats(floatArray) |
|
235 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
|
236 INT _sz1 = __floatArraySize(self); |
|
237 INT _sz2 = __floatArraySize(floatArray); |
|
238 INT i; |
|
239 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
240 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
|
241 |
|
242 if (_sz1 > 0) { |
|
243 if (_sz2 >= _sz1) { |
|
244 /* how about inline-mmx-asm for this ... */ |
|
245 float prev_p1 = _p1[0]; |
|
246 float prev_p2 = _p2[0]; |
|
247 |
|
248 for (i=1; i<_sz1; i++) { |
|
249 float next_p1 = _p1[i]; |
|
250 float next_p2 = _p2[i]; |
|
251 _p1[i-1] = prev_p1 + prev_p2; |
|
252 prev_p1 = next_p1; |
|
253 prev_p2 = next_p2; |
|
254 } |
|
255 _p1[i-1] = prev_p1 + prev_p2; |
|
256 } |
|
257 } |
|
258 RETURN (self); |
|
259 } |
|
260 %}. |
|
261 super primAddArray:floatArray |
|
262 |
|
263 " |
|
264 |f1 f2| |
|
265 |
|
266 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
267 f2 := FloatArray withAll:#(2 2 2 3 3). |
|
268 f1 += f2. |
|
269 f1 |
|
270 " |
|
271 ! |
|
272 |
|
273 primAddScalar: aScalar |
|
274 "add the scalar argument into the receiver (destructive)." |
|
275 |
|
276 %{ |
|
277 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
278 INT _sz1 = __floatArraySize(self); |
|
279 INT i; |
|
280 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
281 float v; |
|
282 float prev_p1; |
|
283 |
|
284 if (_sz1 > 0) { |
|
285 if (__isFloat(aScalar)) { |
|
286 v = (float)(__floatVal(aScalar)); |
|
287 } else if (__isShortFloat(aScalar)) { |
|
288 v = __shortFloatVal(aScalar); |
|
289 } else if (__isSmallInteger(aScalar)) { |
|
290 v = (float)(__intVal(aScalar)); |
|
291 } else |
|
292 goto badArg; |
|
293 |
|
294 /* how about inline-mmx-asm for this ... */ |
|
295 prev_p1 = _p1[0]; |
|
296 for (i=1; i<_sz1; i++) { |
|
297 float next_p1 = _p1[i]; |
|
298 _p1[i-1] = prev_p1 + v; |
|
299 prev_p1 = next_p1; |
|
300 } |
|
301 _p1[i-1] = prev_p1 + v; |
|
302 } |
|
303 RETURN (self); |
|
304 } |
|
305 badArg: ; |
|
306 %}. |
|
307 super primAddScalar:aScalar |
|
308 |
|
309 " |
|
310 |f1 f2| |
|
311 |
|
312 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
313 f1 += 2.0. |
|
314 Transcript showCR:f1. |
|
315 f1 += 2.0 asShortFloat. |
|
316 Transcript showCR:f1. |
|
317 f1 += 2. |
|
318 Transcript showCR:f1. |
|
319 " |
|
320 ! |
|
321 |
|
322 primDivArray: floatArray |
|
323 "divide the vector argument into the receiver (destructive). |
|
324 The argument must be another vector" |
|
325 |
|
326 %{ |
|
327 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
|
328 && __isFloats(floatArray) |
|
329 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
|
330 INT _sz1 = __floatArraySize(self); |
|
331 INT _sz2 = __floatArraySize(floatArray); |
|
332 INT i; |
|
333 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
334 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
|
335 |
|
336 if (_sz1 > 0) { |
|
337 if (_sz2 >= _sz1) { |
|
338 /* how about inline-mmx-asm for this ... */ |
|
339 float prev_p1 = _p1[0]; |
|
340 float prev_p2 = _p2[0]; |
|
341 |
|
342 for (i=1; i<_sz1; i++) { |
|
343 float next_p1 = _p1[i]; |
|
344 float next_p2 = _p2[i]; |
|
345 _p1[i-1] = prev_p1 / prev_p2; |
|
346 prev_p1 = next_p1; |
|
347 prev_p2 = next_p2; |
|
348 } |
|
349 _p1[i-1] = prev_p1 / prev_p2; |
|
350 } |
|
351 } |
|
352 RETURN (self); |
|
353 } |
|
354 %}. |
|
355 super primDivArray: floatArray |
|
356 |
|
357 " |
|
358 |f1 f2| |
|
359 |
|
360 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
361 f2 := FloatArray withAll:#(2 2 2 3 3). |
|
362 f1 /= f2. |
|
363 f1 |
|
364 " |
|
365 |
|
366 "Modified: / 29-05-2007 / 16:01:34 / cg" |
|
367 ! |
|
368 |
|
369 primDivScalar: aScalar |
|
370 "divide the scalar argument into the receiver (destructive)." |
|
371 |
|
372 %{ |
|
373 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
374 INT _sz1 = __floatArraySize(self); |
|
375 INT i; |
|
376 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
377 float v; |
|
378 float prev_p1; |
|
379 |
|
380 if (_sz1 > 0) { |
|
381 if (__isFloat(aScalar)) { |
|
382 v = (float)(__floatVal(aScalar)); |
|
383 } else if (__isShortFloat(aScalar)) { |
|
384 v = __shortFloatVal(aScalar); |
|
385 } else if (__isSmallInteger(aScalar)) { |
|
386 v = (float)(__intVal(aScalar)); |
|
387 } else |
|
388 goto badArg; |
|
389 |
|
390 /* how about inline-mmx-asm for this ... */ |
|
391 prev_p1 = _p1[0]; |
|
392 for (i=1; i<_sz1; i++) { |
|
393 float next_p1 = _p1[i]; |
|
394 _p1[i-1] = prev_p1 / v; |
|
395 prev_p1 = next_p1; |
|
396 } |
|
397 _p1[i-1] = prev_p1 / v; |
|
398 } |
|
399 RETURN (self); |
|
400 } |
|
401 badArg: ; |
|
402 %}. |
|
403 super primDivScalar:aScalar |
|
404 |
|
405 " |
|
406 |f1 f2| |
|
407 |
|
408 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
409 f1 /= 2.0. |
|
410 Transcript showCR:f1. |
|
411 f1 /= 2.0 asShortFloat. |
|
412 Transcript showCR:f1. |
|
413 f1 /= 2. |
|
414 Transcript showCR:f1. |
|
415 " |
|
416 |
|
417 "Modified: / 29-05-2007 / 16:01:39 / cg" |
|
418 ! |
|
419 |
|
420 primMulArray: floatArray |
|
421 "multiply the vector argument into the receiver (destructive). |
|
422 The argument must be another vector" |
|
423 |
|
424 %{ |
|
425 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
|
426 && __isFloats(floatArray) |
|
427 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
|
428 INT _sz1 = __floatArraySize(self); |
|
429 INT _sz2 = __floatArraySize(floatArray); |
|
430 INT i; |
|
431 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
432 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
|
433 |
|
434 if (_sz1 > 0) { |
|
435 if (_sz2 >= _sz1) { |
|
436 float prev_p1 = _p1[0]; |
|
437 float prev_p2 = _p2[0]; |
|
438 |
|
439 for (i=1; i<_sz1; i++) { |
|
440 float next_p1 = _p1[i]; |
|
441 float next_p2 = _p2[i]; |
|
442 _p1[i-1] = prev_p1 * prev_p2; |
|
443 prev_p1 = next_p1; |
|
444 prev_p2 = next_p2; |
|
445 } |
|
446 _p1[i-1] = prev_p1 * prev_p2; |
|
447 } |
|
448 } |
|
449 RETURN (self); |
|
450 } |
|
451 %}. |
|
452 super primMulArray: floatArray |
|
453 |
|
454 " |
|
455 |f1 f2| |
|
456 |
|
457 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
458 f2 := FloatArray withAll:#(2 2 2 3 3). |
|
459 f1 *= f2. |
|
460 f1 |
|
461 " |
|
462 ! |
|
463 |
|
464 primMulScalar: aScalar |
|
465 "multiply the scalar argument into the receiver (destructive)." |
|
466 |
|
467 %{ |
|
468 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
469 INT _sz1 = __floatArraySize(self); |
|
470 INT i; |
|
471 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
472 float v; |
|
473 float prev_p1; |
|
474 |
|
475 if (_sz1 > 0) { |
|
476 if (__isFloat(aScalar)) { |
|
477 v = (float)(__floatVal(aScalar)); |
|
478 } else if (__isShortFloat(aScalar)) { |
|
479 v = __shortFloatVal(aScalar); |
|
480 } else if (__isSmallInteger(aScalar)) { |
|
481 v = (float)(__intVal(aScalar)); |
|
482 } else |
|
483 goto badArg; |
|
484 |
|
485 /* how about inline-mmx-asm for this ... */ |
|
486 prev_p1 = _p1[0]; |
|
487 for (i=1; i<_sz1; i++) { |
|
488 float next_p1 = _p1[i]; |
|
489 _p1[i-1] = prev_p1 * v; |
|
490 prev_p1 = next_p1; |
|
491 } |
|
492 _p1[i-1] = prev_p1 * v; |
|
493 } |
|
494 RETURN (self); |
|
495 } |
|
496 badArg: ; |
|
497 %}. |
|
498 super primMulScalar:aScalar |
|
499 |
|
500 " |
|
501 |f1 f2| |
|
502 |
|
503 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
504 f1 *= 2.0. |
|
505 Transcript showCR:f1. |
|
506 f1 *= 2.0 asShortFloat. |
|
507 Transcript showCR:f1. |
|
508 f1 *= 2. |
|
509 Transcript showCR:f1. |
|
510 " |
|
511 ! |
|
512 |
|
513 primNegated |
|
514 "destructive negative value of each element" |
|
515 |
|
516 %{ |
|
517 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
518 INT _sz = __floatArraySize(self); |
|
519 INT i; |
|
520 float *_p = __FloatArrayInstPtr(self)->f_element; |
|
521 float prev_p; |
|
522 |
|
523 if (_sz > 0) { |
|
524 /* how about inline-mmx-asm for this ... */ |
|
525 prev_p = _p[0]; |
|
526 for (i=1; i<_sz; i++) { |
|
527 float next_p = _p[i]; |
|
528 |
|
529 _p[i-1] = -prev_p; |
|
530 prev_p = next_p; |
|
531 } |
|
532 _p[i-1] = -prev_p; |
|
533 } |
|
534 RETURN (self); |
|
535 } |
|
536 %}. |
|
537 super primNegated |
|
538 |
|
539 " |
|
540 |f| |
|
541 |
|
542 f := FloatArray withAll:#(-1 2 -3 4 -5). |
|
543 f negated. |
|
544 f |
|
545 " |
|
546 |
|
547 "Created: / 30-05-2007 / 17:51:29 / cg" |
|
548 ! |
|
549 |
|
550 primSubtractArray: floatArray |
|
551 "subtract the vector argument from the receiver (destructive). |
|
552 The argument must be another vector" |
|
553 |
|
554 %{ |
|
555 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
|
556 && __isFloats(floatArray) |
|
557 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
|
558 INT _sz1 = __floatArraySize(self); |
|
559 INT _sz2 = __floatArraySize(floatArray); |
|
560 INT i; |
|
561 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
562 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
|
563 |
|
564 if (_sz1 > 0) { |
|
565 if (_sz2 >= _sz1) { |
|
566 float prev_p1 = _p1[0]; |
|
567 float prev_p2 = _p2[0]; |
|
568 |
|
569 for (i=1; i<_sz1; i++) { |
|
570 float next_p1 = _p1[i]; |
|
571 float next_p2 = _p2[i]; |
|
572 _p1[i-1] = prev_p1 - prev_p2; |
|
573 prev_p1 = next_p1; |
|
574 prev_p2 = next_p2; |
|
575 } |
|
576 _p1[i-1] = prev_p1 - prev_p2; |
|
577 } |
|
578 } |
|
579 RETURN (self); |
|
580 } |
|
581 %}. |
|
582 super primSubtractArray: floatArray |
|
583 |
|
584 " |
|
585 |f1 f2| |
|
586 |
|
587 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
588 f2 := FloatArray withAll:#(2 2 2 3 3). |
|
589 f1 -= f2. |
|
590 f1 |
|
591 " |
|
592 |
|
593 "Created: / 30-05-2007 / 17:42:41 / cg" |
|
594 ! |
|
595 |
|
596 primSubtractScalar: aScalar |
|
597 "subtract the scalar argument from the receiver (destructive)." |
|
598 |
|
599 %{ |
|
600 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
|
601 INT _sz1 = __floatArraySize(self); |
|
602 INT i; |
|
603 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
|
604 float v; |
|
605 float prev_p1; |
|
606 |
|
607 if (_sz1 > 0) { |
|
608 if (__isFloat(aScalar)) { |
|
609 v = (float)(__floatVal(aScalar)); |
|
610 } else if (__isShortFloat(aScalar)) { |
|
611 v = __shortFloatVal(aScalar); |
|
612 } else if (__isSmallInteger(aScalar)) { |
|
613 v = (float)(__intVal(aScalar)); |
|
614 } else |
|
615 goto badArg; |
|
616 |
|
617 /* how about inline-mmx-asm for this... ? */ |
|
618 prev_p1 = _p1[0]; |
|
619 for (i=1; i<_sz1; i++) { |
|
620 float next_p1 = _p1[i]; |
|
621 _p1[i-1] = prev_p1 - v; |
|
622 prev_p1 = next_p1; |
|
623 } |
|
624 _p1[i-1] = prev_p1 - v; |
|
625 } |
|
626 RETURN (self); |
|
627 } |
|
628 badArg: ; |
|
629 %}. |
|
630 super primSubtractScalar:aScalar |
|
631 |
|
632 " |
|
633 |f1 f2| |
|
634 |
|
635 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
636 f1 -= 2.0. |
|
637 Transcript showCR:f1. |
|
638 f1 -= 2.0 asShortFloat. |
|
639 Transcript showCR:f1. |
|
640 f1 -= 2. |
|
641 Transcript showCR:f1. |
|
642 " |
|
643 |
|
644 "Created: / 30-05-2007 / 17:43:06 / cg" |
|
645 ! ! |
|
646 |
713 !FloatArray methodsFor:'queries'! |
647 !FloatArray methodsFor:'queries'! |
714 |
|
715 absMax |
|
716 "return the largest absolute value" |
|
717 |
|
718 |minMax| |
|
719 |
|
720 minMax := self minMax. |
|
721 ^ (minMax at:1) abs max:(minMax at:2) abs |
|
722 |
|
723 " |
|
724 |f1| |
|
725 |
|
726 f1 := (1 to:1000) asFloatArray. |
|
727 Time millisecondsToRun:[ 1000 timesRepeat:[ f1 absMax ] ] |
|
728 " |
|
729 |
|
730 " |
|
731 |f1| |
|
732 |
|
733 f1 := FloatArray withAll:#(1 2 3 4 5). |
|
734 f1 absMax |
|
735 " |
|
736 " |
|
737 |f1| |
|
738 |
|
739 f1 := FloatArray withAll:#(5 4 3 2 1). |
|
740 f1 absMax |
|
741 " |
|
742 " |
|
743 |f1| |
|
744 |
|
745 f1 := FloatArray withAll:#(5 -4 3 2 1). |
|
746 f1 absMax |
|
747 " |
|
748 " |
|
749 |f1| |
|
750 |
|
751 f1 := FloatArray withAll:#(5 -5 3 2 1). |
|
752 f1 absMax |
|
753 " |
|
754 " |
|
755 |f1| |
|
756 |
|
757 f1 := FloatArray withAll:#(5 -6 3 2 1). |
|
758 f1 absMax |
|
759 " |
|
760 ! |
|
761 |
648 |
762 defaultElement |
649 defaultElement |
763 ^ ShortFloat zero |
650 ^ ShortFloat zero |
764 ! |
|
765 |
|
766 length |
|
767 "Return the length of the receiver interpreted as vector |
|
768 (that is the length of the vector from 0.0 @ 0.0 @ ... @ 0.0 |
|
769 to the point in the n-dimensional space represented by the receiver)" |
|
770 |
|
771 ^ self squaredLength sqrt |
|
772 |
|
773 " |
|
774 #(10.0 10.0) asFloatArray length |
|
775 #(10.0 10.0 10.0) asFloatArray length |
|
776 " |
|
777 ! |
651 ! |
778 |
652 |
779 max |
653 max |
780 "return the largest element; |
654 "return the largest element; |
781 redefined for speed" |
655 redefined for speed" |
978 "/ <primitive:'primitiveDotProduct' module: 'FloatArrayPlugin'> |
846 "/ <primitive:'primitiveDotProduct' module: 'FloatArrayPlugin'> |
979 %{ |
847 %{ |
980 if (__isFloats(aFloatVector) |
848 if (__isFloats(aFloatVector) |
981 && (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
849 && (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
982 && (__ClassInstPtr(__qClass(aFloatVector))->c_ninstvars == __mkSmallInteger(0))) { |
850 && (__ClassInstPtr(__qClass(aFloatVector))->c_ninstvars == __mkSmallInteger(0))) { |
983 INT __mySize = __floatArraySize(self); |
851 INT __mySize = __floatArraySize(self); |
984 INT __otherSize = __floatArraySize(aFloatVector); |
852 INT __otherSize = __floatArraySize(aFloatVector); |
985 if (__mySize == __otherSize) { |
853 float __result = 0.0; |
986 float *__p1 = __FloatArrayInstPtr(self)->f_element; |
854 |
987 float *__p2 = __FloatArrayInstPtr(aFloatVector)->f_element; |
855 if (__mySize == __otherSize) { |
988 float __result = 0.0; |
856 if (__mySize > 0) { |
989 INT __i; |
857 float *__p1 = __FloatArrayInstPtr(self)->f_element; |
990 |
858 float *__p2 = __FloatArrayInstPtr(aFloatVector)->f_element; |
991 /* how about inline-mmx-asm for this ... */ |
859 INT __i; |
992 for (__i=0; __i<__mySize; __i++) { |
860 /* how about inline-mmx-asm for this ... */ |
993 __result = __result + (__p1[__i] * __p2[__i]); |
861 for (__i=0; __i<__mySize; __i++) { |
994 } |
862 __result += (__p1[__i] * __p2[__i]); |
995 RETURN (__MKFLOAT(__result)); |
863 } |
996 } |
864 } |
997 } |
865 RETURN (__MKFLOAT(__result)); |
998 %}. |
866 } |
999 |
867 } |
1000 mySize := self size. |
868 %}. |
1001 mySize = aFloatVector size ifFalse:[^self error:'Must be of equal size']. |
869 ^ super dot:aFloatVector |
1002 result := 0.0. |
|
1003 1 to: mySize do:[:i| |
|
1004 result := result + ((self at: i) * (aFloatVector at: i)). |
|
1005 ]. |
|
1006 ^result |
|
1007 |
870 |
1008 " |
871 " |
1009 |v| |
872 |v| |
1010 |
873 |
1011 v := #(2.0 2.0 1.0) asFloatArray. |
874 v := #(2.0 2.0 1.0) asFloatArray. |
1012 v dot:v. |
875 v dot:v. |
|
876 " |
|
877 " |
|
878 |v1 v2| |
|
879 |
|
880 v1 := FloatArray new:10000 withAll:2. |
|
881 v2 := FloatArray new:10000 withAll:3. |
|
882 Time millisecondsToRun:[ |
|
883 10000 timesRepeat:[ |
|
884 v1 dot:v2. |
|
885 ] |
|
886 ] |
1013 " |
887 " |
1014 |
888 |
1015 "Created: / 29-05-2007 / 13:13:39 / cg" |
889 "Created: / 29-05-2007 / 13:13:39 / cg" |
1016 ! ! |
890 ! ! |
1017 |
891 |
|
892 |
1018 !FloatArray class methodsFor:'documentation'! |
893 !FloatArray class methodsFor:'documentation'! |
1019 |
894 |
1020 version |
895 version |
1021 ^ '$Header: /cvs/stx/stx/libbasic/FloatArray.st,v 1.31 2013-01-23 18:03:01 cg Exp $' |
896 ^ '$Header: /cvs/stx/stx/libbasic/FloatArray.st,v 1.35 2014-12-08 17:30:24 cg Exp $' |
1022 ! |
897 ! |
1023 |
898 |
1024 version_CVS |
899 version_CVS |
1025 ^ '$Header: /cvs/stx/stx/libbasic/FloatArray.st,v 1.31 2013-01-23 18:03:01 cg Exp $' |
900 ^ '$Header: /cvs/stx/stx/libbasic/FloatArray.st,v 1.35 2014-12-08 17:30:24 cg Exp $' |
1026 ! ! |
901 ! ! |
|
902 |