40 |
40 |
41 documentation |
41 documentation |
42 " |
42 " |
43 FloatArrays store floats (and nothing else). |
43 FloatArrays store floats (and nothing else). |
44 They have been added to support heavy duty number crunching and |
44 They have been added to support heavy duty number crunching and |
45 data exchange with openGL frameworks and other mass data libraries. |
45 data exchange with openGL frameworks and other mass data libraries. |
46 See documentation in DoubleArray for more information. |
46 See documentation in DoubleArray for more information. |
47 |
47 |
48 [memory requirements:] |
48 [memory requirements:] |
49 OBJ-HEADER + (size * float-size) |
49 OBJ-HEADER + (size * float-size) |
50 |
50 |
51 [See also:] |
51 [See also:] |
52 DoubleArray Array |
52 DoubleArray Array |
53 |
53 |
54 [author:] |
54 [author:] |
55 Claus Gittinger |
55 Claus Gittinger |
56 " |
56 " |
57 ! ! |
57 ! ! |
58 |
58 |
59 !FloatArray class methodsFor:'queries'! |
59 !FloatArray class methodsFor:'queries'! |
60 |
60 |
140 ! |
140 ! |
141 |
141 |
142 replaceFrom:start to:stop with:aCollection startingAt:replStart |
142 replaceFrom:start to:stop with:aCollection startingAt:replStart |
143 %{ |
143 %{ |
144 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
144 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
145 && __isFloats(aCollection) |
145 && __isFloats(aCollection) |
146 && (__ClassInstPtr(__qClass(aCollection))->c_ninstvars == __mkSmallInteger(0)) |
146 && (__ClassInstPtr(__qClass(aCollection))->c_ninstvars == __mkSmallInteger(0)) |
147 && __bothSmallInteger(start, stop) |
147 && __bothSmallInteger(start, stop) |
148 && __isSmallInteger(replStart) |
148 && __isSmallInteger(replStart) |
149 ) { |
149 ) { |
150 INT __start = __intVal(start) - 1; |
150 INT __start = __intVal(start) - 1; |
151 INT __stop = __intVal(stop) - 1 ; |
151 INT __stop = __intVal(stop) - 1 ; |
152 INT __replStart = __intVal(replStart) - 1 ; |
152 INT __replStart = __intVal(replStart) - 1 ; |
153 |
153 |
154 if (__stop >= __start) { |
154 if (__stop >= __start) { |
155 INT __sz = __floatArraySize(self); |
155 INT __sz = __floatArraySize(self); |
156 INT __otherSz = __floatArraySize(aCollection); |
156 INT __otherSz = __floatArraySize(aCollection); |
157 INT __replStop = __replStart + (__stop-__start); |
157 INT __replStop = __replStart + (__stop-__start); |
158 |
158 |
159 if (((unsigned INT)__start < __sz) |
159 if (((unsigned INT)__start < __sz) |
160 && ((unsigned INT)__stop < __sz) |
160 && ((unsigned INT)__stop < __sz) |
161 && ((unsigned INT)__replStart < __otherSz) |
161 && ((unsigned INT)__replStart < __otherSz) |
162 && ((unsigned INT)__replStop < __otherSz)) { |
162 && ((unsigned INT)__replStop < __otherSz)) { |
163 INT __n = __stop - __start + 1; |
163 INT __n = __stop - __start + 1; |
164 |
164 |
165 if (aCollection == self) { |
165 if (aCollection == self) { |
166 memmove(&(__FloatArrayInstPtr(self)->f_element[__start]), |
166 memmove(&(__FloatArrayInstPtr(self)->f_element[__start]), |
167 &(__FloatArrayInstPtr(aCollection)->f_element[__replStart]), |
167 &(__FloatArrayInstPtr(aCollection)->f_element[__replStart]), |
168 sizeof(float) * __n); |
168 sizeof(float) * __n); |
169 } else { |
169 } else { |
170 memcpy(&(__FloatArrayInstPtr(self)->f_element[__start]), |
170 memcpy(&(__FloatArrayInstPtr(self)->f_element[__start]), |
171 &(__FloatArrayInstPtr(aCollection)->f_element[__replStart]), |
171 &(__FloatArrayInstPtr(aCollection)->f_element[__replStart]), |
172 sizeof(float) * __n); |
172 sizeof(float) * __n); |
173 } |
173 } |
174 RETURN(self); |
174 RETURN(self); |
175 } |
175 } |
176 } |
176 } |
177 } |
177 } |
178 %}. |
178 %}. |
179 ^ super replaceFrom:start to:stop with:aCollection startingAt:replStart |
179 ^ super replaceFrom:start to:stop with:aCollection startingAt:replStart |
180 |
180 |
181 " |
181 " |
192 primAbs |
192 primAbs |
193 "destructive absolute value of each element" |
193 "destructive absolute value of each element" |
194 |
194 |
195 %{ |
195 %{ |
196 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
196 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
197 INT _sz = __floatArraySize(self); |
197 INT _sz = __floatArraySize(self); |
198 INT i; |
198 INT i; |
199 float *_p = __FloatArrayInstPtr(self)->f_element; |
199 float *_p = __FloatArrayInstPtr(self)->f_element; |
200 float prev_p; |
200 float prev_p; |
201 |
201 |
202 if (_sz > 0) { |
202 if (_sz > 0) { |
203 /* how about inline-mmx-asm for this ... */ |
203 /* how about inline-mmx-asm for this ... */ |
204 prev_p = _p[0]; |
204 prev_p = _p[0]; |
205 for (i=1; i<_sz; i++) { |
205 for (i=1; i<_sz; i++) { |
206 float next_p = _p[i]; |
206 float next_p = _p[i]; |
207 |
207 |
208 if (prev_p < 0) { |
208 if (prev_p < 0) { |
209 _p[i-1] = -prev_p; |
209 _p[i-1] = -prev_p; |
210 } |
210 } |
211 prev_p = next_p; |
211 prev_p = next_p; |
212 } |
212 } |
213 if (prev_p < 0) { |
213 if (prev_p < 0) { |
214 _p[i-1] = -prev_p; |
214 _p[i-1] = -prev_p; |
215 } |
215 } |
216 } |
216 } |
217 RETURN (self); |
217 RETURN (self); |
218 } |
218 } |
219 %}. |
219 %}. |
220 super primAbs |
220 super primAbs |
221 |
221 |
222 " |
222 " |
236 |
236 |
237 %{ |
237 %{ |
238 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
238 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
239 && __isFloats(floatArray) |
239 && __isFloats(floatArray) |
240 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
240 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
241 INT _sz1 = __floatArraySize(self); |
241 INT _sz1 = __floatArraySize(self); |
242 INT _sz2 = __floatArraySize(floatArray); |
242 INT _sz2 = __floatArraySize(floatArray); |
243 INT i; |
243 INT i; |
244 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
244 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
245 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
245 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
246 |
246 |
247 if (_sz1 > 0) { |
247 if (_sz1 > 0) { |
248 if (_sz2 >= _sz1) { |
248 if (_sz2 >= _sz1) { |
249 /* how about inline-mmx-asm for this ... */ |
249 /* how about inline-mmx-asm for this ... */ |
250 float prev_p1 = _p1[0]; |
250 float prev_p1 = _p1[0]; |
251 float prev_p2 = _p2[0]; |
251 float prev_p2 = _p2[0]; |
252 |
252 |
253 for (i=1; i<_sz1; i++) { |
253 for (i=1; i<_sz1; i++) { |
254 float next_p1 = _p1[i]; |
254 float next_p1 = _p1[i]; |
255 float next_p2 = _p2[i]; |
255 float next_p2 = _p2[i]; |
256 _p1[i-1] = prev_p1 + prev_p2; |
256 _p1[i-1] = prev_p1 + prev_p2; |
257 prev_p1 = next_p1; |
257 prev_p1 = next_p1; |
258 prev_p2 = next_p2; |
258 prev_p2 = next_p2; |
259 } |
259 } |
260 _p1[i-1] = prev_p1 + prev_p2; |
260 _p1[i-1] = prev_p1 + prev_p2; |
261 } |
261 } |
262 } |
262 } |
263 RETURN (self); |
263 RETURN (self); |
264 } |
264 } |
265 %}. |
265 %}. |
266 super primAddArray:floatArray |
266 super primAddArray:floatArray |
267 |
267 |
268 " |
268 " |
278 primAddScalar: aScalar |
278 primAddScalar: aScalar |
279 "add the scalar argument into the receiver (destructive)." |
279 "add the scalar argument into the receiver (destructive)." |
280 |
280 |
281 %{ |
281 %{ |
282 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
282 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
283 INT _sz1 = __floatArraySize(self); |
283 INT _sz1 = __floatArraySize(self); |
284 INT i; |
284 INT i; |
285 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
285 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
286 float v; |
286 float v; |
287 float prev_p1; |
287 float prev_p1; |
288 |
288 |
289 if (_sz1 > 0) { |
289 if (_sz1 > 0) { |
290 if (__isFloat(aScalar)) { |
290 if (__isFloat(aScalar)) { |
291 v = (float)(__floatVal(aScalar)); |
291 v = (float)(__floatVal(aScalar)); |
292 } else if (__isShortFloat(aScalar)) { |
292 } else if (__isShortFloat(aScalar)) { |
293 v = __shortFloatVal(aScalar); |
293 v = __shortFloatVal(aScalar); |
294 } else if (__isSmallInteger(aScalar)) { |
294 } else if (__isSmallInteger(aScalar)) { |
295 v = (float)(__intVal(aScalar)); |
295 v = (float)(__intVal(aScalar)); |
296 } else |
296 } else |
297 goto badArg; |
297 goto badArg; |
298 |
298 |
299 /* how about inline-mmx-asm for this ... */ |
299 /* how about inline-mmx-asm for this ... */ |
300 prev_p1 = _p1[0]; |
300 prev_p1 = _p1[0]; |
301 for (i=1; i<_sz1; i++) { |
301 for (i=1; i<_sz1; i++) { |
302 float next_p1 = _p1[i]; |
302 float next_p1 = _p1[i]; |
303 _p1[i-1] = prev_p1 + v; |
303 _p1[i-1] = prev_p1 + v; |
304 prev_p1 = next_p1; |
304 prev_p1 = next_p1; |
305 } |
305 } |
306 _p1[i-1] = prev_p1 + v; |
306 _p1[i-1] = prev_p1 + v; |
307 } |
307 } |
308 RETURN (self); |
308 RETURN (self); |
309 } |
309 } |
310 badArg: ; |
310 badArg: ; |
311 %}. |
311 %}. |
312 super primAddScalar:aScalar |
312 super primAddScalar:aScalar |
313 |
313 |
330 |
330 |
331 %{ |
331 %{ |
332 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
332 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
333 && __isFloats(floatArray) |
333 && __isFloats(floatArray) |
334 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
334 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
335 INT _sz1 = __floatArraySize(self); |
335 INT _sz1 = __floatArraySize(self); |
336 INT _sz2 = __floatArraySize(floatArray); |
336 INT _sz2 = __floatArraySize(floatArray); |
337 INT i; |
337 INT i; |
338 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
338 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
339 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
339 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
340 |
340 |
341 if (_sz1 > 0) { |
341 if (_sz1 > 0) { |
342 if (_sz2 >= _sz1) { |
342 if (_sz2 >= _sz1) { |
343 /* how about inline-mmx-asm for this ... */ |
343 /* how about inline-mmx-asm for this ... */ |
344 float prev_p1 = _p1[0]; |
344 float prev_p1 = _p1[0]; |
345 float prev_p2 = _p2[0]; |
345 float prev_p2 = _p2[0]; |
346 |
346 |
347 for (i=1; i<_sz1; i++) { |
347 for (i=1; i<_sz1; i++) { |
348 float next_p1 = _p1[i]; |
348 float next_p1 = _p1[i]; |
349 float next_p2 = _p2[i]; |
349 float next_p2 = _p2[i]; |
350 _p1[i-1] = prev_p1 / prev_p2; |
350 _p1[i-1] = prev_p1 / prev_p2; |
351 prev_p1 = next_p1; |
351 prev_p1 = next_p1; |
352 prev_p2 = next_p2; |
352 prev_p2 = next_p2; |
353 } |
353 } |
354 _p1[i-1] = prev_p1 / prev_p2; |
354 _p1[i-1] = prev_p1 / prev_p2; |
355 } |
355 } |
356 } |
356 } |
357 RETURN (self); |
357 RETURN (self); |
358 } |
358 } |
359 %}. |
359 %}. |
360 super primDivArray: floatArray |
360 super primDivArray: floatArray |
361 |
361 |
362 " |
362 " |
374 primDivScalar: aScalar |
374 primDivScalar: aScalar |
375 "divide the scalar argument into the receiver (destructive)." |
375 "divide the scalar argument into the receiver (destructive)." |
376 |
376 |
377 %{ |
377 %{ |
378 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
378 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
379 INT _sz1 = __floatArraySize(self); |
379 INT _sz1 = __floatArraySize(self); |
380 INT i; |
380 INT i; |
381 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
381 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
382 float v; |
382 float v; |
383 float prev_p1; |
383 float prev_p1; |
384 |
384 |
385 if (_sz1 > 0) { |
385 if (_sz1 > 0) { |
386 if (__isFloat(aScalar)) { |
386 if (__isFloat(aScalar)) { |
387 v = (float)(__floatVal(aScalar)); |
387 v = (float)(__floatVal(aScalar)); |
388 } else if (__isShortFloat(aScalar)) { |
388 } else if (__isShortFloat(aScalar)) { |
389 v = __shortFloatVal(aScalar); |
389 v = __shortFloatVal(aScalar); |
390 } else if (__isSmallInteger(aScalar)) { |
390 } else if (__isSmallInteger(aScalar)) { |
391 v = (float)(__intVal(aScalar)); |
391 v = (float)(__intVal(aScalar)); |
392 } else |
392 } else |
393 goto badArg; |
393 goto badArg; |
394 |
394 |
395 /* how about inline-mmx-asm for this ... */ |
395 /* how about inline-mmx-asm for this ... */ |
396 prev_p1 = _p1[0]; |
396 prev_p1 = _p1[0]; |
397 for (i=1; i<_sz1; i++) { |
397 for (i=1; i<_sz1; i++) { |
398 float next_p1 = _p1[i]; |
398 float next_p1 = _p1[i]; |
399 _p1[i-1] = prev_p1 / v; |
399 _p1[i-1] = prev_p1 / v; |
400 prev_p1 = next_p1; |
400 prev_p1 = next_p1; |
401 } |
401 } |
402 _p1[i-1] = prev_p1 / v; |
402 _p1[i-1] = prev_p1 / v; |
403 } |
403 } |
404 RETURN (self); |
404 RETURN (self); |
405 } |
405 } |
406 badArg: ; |
406 badArg: ; |
407 %}. |
407 %}. |
408 super primDivScalar:aScalar |
408 super primDivScalar:aScalar |
409 |
409 |
428 |
428 |
429 %{ |
429 %{ |
430 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
430 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
431 && __isFloats(floatArray) |
431 && __isFloats(floatArray) |
432 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
432 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
433 INT _sz1 = __floatArraySize(self); |
433 INT _sz1 = __floatArraySize(self); |
434 INT _sz2 = __floatArraySize(floatArray); |
434 INT _sz2 = __floatArraySize(floatArray); |
435 INT i; |
435 INT i; |
436 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
436 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
437 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
437 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
438 |
438 |
439 if (_sz1 > 0) { |
439 if (_sz1 > 0) { |
440 if (_sz2 >= _sz1) { |
440 if (_sz2 >= _sz1) { |
441 float prev_p1 = _p1[0]; |
441 float prev_p1 = _p1[0]; |
442 float prev_p2 = _p2[0]; |
442 float prev_p2 = _p2[0]; |
443 |
443 |
444 for (i=1; i<_sz1; i++) { |
444 for (i=1; i<_sz1; i++) { |
445 float next_p1 = _p1[i]; |
445 float next_p1 = _p1[i]; |
446 float next_p2 = _p2[i]; |
446 float next_p2 = _p2[i]; |
447 _p1[i-1] = prev_p1 * prev_p2; |
447 _p1[i-1] = prev_p1 * prev_p2; |
448 prev_p1 = next_p1; |
448 prev_p1 = next_p1; |
449 prev_p2 = next_p2; |
449 prev_p2 = next_p2; |
450 } |
450 } |
451 _p1[i-1] = prev_p1 * prev_p2; |
451 _p1[i-1] = prev_p1 * prev_p2; |
452 } |
452 } |
453 } |
453 } |
454 RETURN (self); |
454 RETURN (self); |
455 } |
455 } |
456 %}. |
456 %}. |
457 super primMulArray: floatArray |
457 super primMulArray: floatArray |
458 |
458 |
459 " |
459 " |
469 primMulScalar: aScalar |
469 primMulScalar: aScalar |
470 "multiply the scalar argument into the receiver (destructive)." |
470 "multiply the scalar argument into the receiver (destructive)." |
471 |
471 |
472 %{ |
472 %{ |
473 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
473 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
474 INT _sz1 = __floatArraySize(self); |
474 INT _sz1 = __floatArraySize(self); |
475 INT i; |
475 INT i; |
476 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
476 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
477 float v; |
477 float v; |
478 float prev_p1; |
478 float prev_p1; |
479 |
479 |
480 if (_sz1 > 0) { |
480 if (_sz1 > 0) { |
481 if (__isFloat(aScalar)) { |
481 if (__isFloat(aScalar)) { |
482 v = (float)(__floatVal(aScalar)); |
482 v = (float)(__floatVal(aScalar)); |
483 } else if (__isShortFloat(aScalar)) { |
483 } else if (__isShortFloat(aScalar)) { |
484 v = __shortFloatVal(aScalar); |
484 v = __shortFloatVal(aScalar); |
485 } else if (__isSmallInteger(aScalar)) { |
485 } else if (__isSmallInteger(aScalar)) { |
486 v = (float)(__intVal(aScalar)); |
486 v = (float)(__intVal(aScalar)); |
487 } else |
487 } else |
488 goto badArg; |
488 goto badArg; |
489 |
489 |
490 /* how about inline-mmx-asm for this ... */ |
490 /* how about inline-mmx-asm for this ... */ |
491 prev_p1 = _p1[0]; |
491 prev_p1 = _p1[0]; |
492 for (i=1; i<_sz1; i++) { |
492 for (i=1; i<_sz1; i++) { |
493 float next_p1 = _p1[i]; |
493 float next_p1 = _p1[i]; |
494 _p1[i-1] = prev_p1 * v; |
494 _p1[i-1] = prev_p1 * v; |
495 prev_p1 = next_p1; |
495 prev_p1 = next_p1; |
496 } |
496 } |
497 _p1[i-1] = prev_p1 * v; |
497 _p1[i-1] = prev_p1 * v; |
498 } |
498 } |
499 RETURN (self); |
499 RETURN (self); |
500 } |
500 } |
501 badArg: ; |
501 badArg: ; |
502 %}. |
502 %}. |
503 super primMulScalar:aScalar |
503 super primMulScalar:aScalar |
504 |
504 |
518 primNegated |
518 primNegated |
519 "destructive negative value of each element" |
519 "destructive negative value of each element" |
520 |
520 |
521 %{ |
521 %{ |
522 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
522 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
523 INT _sz = __floatArraySize(self); |
523 INT _sz = __floatArraySize(self); |
524 INT i; |
524 INT i; |
525 float *_p = __FloatArrayInstPtr(self)->f_element; |
525 float *_p = __FloatArrayInstPtr(self)->f_element; |
526 float prev_p; |
526 float prev_p; |
527 |
527 |
528 if (_sz > 0) { |
528 if (_sz > 0) { |
529 /* how about inline-mmx-asm for this ... */ |
529 /* how about inline-mmx-asm for this ... */ |
530 prev_p = _p[0]; |
530 prev_p = _p[0]; |
531 for (i=1; i<_sz; i++) { |
531 for (i=1; i<_sz; i++) { |
532 float next_p = _p[i]; |
532 float next_p = _p[i]; |
533 |
533 |
534 _p[i-1] = -prev_p; |
534 _p[i-1] = -prev_p; |
535 prev_p = next_p; |
535 prev_p = next_p; |
536 } |
536 } |
537 _p[i-1] = -prev_p; |
537 _p[i-1] = -prev_p; |
538 } |
538 } |
539 RETURN (self); |
539 RETURN (self); |
540 } |
540 } |
541 %}. |
541 %}. |
542 super primNegated |
542 super primNegated |
543 |
543 |
544 " |
544 " |
558 |
558 |
559 %{ |
559 %{ |
560 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
560 if ((__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
561 && __isFloats(floatArray) |
561 && __isFloats(floatArray) |
562 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
562 && (__ClassInstPtr(__qClass(floatArray))->c_ninstvars == __mkSmallInteger(0))) { |
563 INT _sz1 = __floatArraySize(self); |
563 INT _sz1 = __floatArraySize(self); |
564 INT _sz2 = __floatArraySize(floatArray); |
564 INT _sz2 = __floatArraySize(floatArray); |
565 INT i; |
565 INT i; |
566 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
566 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
567 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
567 float *_p2 = __FloatArrayInstPtr(floatArray)->f_element; |
568 |
568 |
569 if (_sz1 > 0) { |
569 if (_sz1 > 0) { |
570 if (_sz2 >= _sz1) { |
570 if (_sz2 >= _sz1) { |
571 float prev_p1 = _p1[0]; |
571 float prev_p1 = _p1[0]; |
572 float prev_p2 = _p2[0]; |
572 float prev_p2 = _p2[0]; |
573 |
573 |
574 for (i=1; i<_sz1; i++) { |
574 for (i=1; i<_sz1; i++) { |
575 float next_p1 = _p1[i]; |
575 float next_p1 = _p1[i]; |
576 float next_p2 = _p2[i]; |
576 float next_p2 = _p2[i]; |
577 _p1[i-1] = prev_p1 - prev_p2; |
577 _p1[i-1] = prev_p1 - prev_p2; |
578 prev_p1 = next_p1; |
578 prev_p1 = next_p1; |
579 prev_p2 = next_p2; |
579 prev_p2 = next_p2; |
580 } |
580 } |
581 _p1[i-1] = prev_p1 - prev_p2; |
581 _p1[i-1] = prev_p1 - prev_p2; |
582 } |
582 } |
583 } |
583 } |
584 RETURN (self); |
584 RETURN (self); |
585 } |
585 } |
586 %}. |
586 %}. |
587 super primSubtractArray: floatArray |
587 super primSubtractArray: floatArray |
588 |
588 |
589 " |
589 " |
601 primSubtractScalar: aScalar |
601 primSubtractScalar: aScalar |
602 "subtract the scalar argument from the receiver (destructive)." |
602 "subtract the scalar argument from the receiver (destructive)." |
603 |
603 |
604 %{ |
604 %{ |
605 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
605 if (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) { |
606 INT _sz1 = __floatArraySize(self); |
606 INT _sz1 = __floatArraySize(self); |
607 INT i; |
607 INT i; |
608 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
608 float *_p1 = __FloatArrayInstPtr(self)->f_element; |
609 float v; |
609 float v; |
610 float prev_p1; |
610 float prev_p1; |
611 |
611 |
612 if (_sz1 > 0) { |
612 if (_sz1 > 0) { |
613 if (__isFloat(aScalar)) { |
613 if (__isFloat(aScalar)) { |
614 v = (float)(__floatVal(aScalar)); |
614 v = (float)(__floatVal(aScalar)); |
615 } else if (__isShortFloat(aScalar)) { |
615 } else if (__isShortFloat(aScalar)) { |
616 v = __shortFloatVal(aScalar); |
616 v = __shortFloatVal(aScalar); |
617 } else if (__isSmallInteger(aScalar)) { |
617 } else if (__isSmallInteger(aScalar)) { |
618 v = (float)(__intVal(aScalar)); |
618 v = (float)(__intVal(aScalar)); |
619 } else |
619 } else |
620 goto badArg; |
620 goto badArg; |
621 |
621 |
622 /* how about inline-mmx-asm for this... ? */ |
622 /* how about inline-mmx-asm for this... ? */ |
623 prev_p1 = _p1[0]; |
623 prev_p1 = _p1[0]; |
624 for (i=1; i<_sz1; i++) { |
624 for (i=1; i<_sz1; i++) { |
625 float next_p1 = _p1[i]; |
625 float next_p1 = _p1[i]; |
626 _p1[i-1] = prev_p1 - v; |
626 _p1[i-1] = prev_p1 - v; |
627 prev_p1 = next_p1; |
627 prev_p1 = next_p1; |
628 } |
628 } |
629 _p1[i-1] = prev_p1 - v; |
629 _p1[i-1] = prev_p1 - v; |
630 } |
630 } |
631 RETURN (self); |
631 RETURN (self); |
632 } |
632 } |
633 badArg: ; |
633 badArg: ; |
634 %}. |
634 %}. |
635 super primSubtractScalar:aScalar |
635 super primSubtractScalar:aScalar |
636 |
636 |
851 "/ <primitive:'primitiveDotProduct' module: 'FloatArrayPlugin'> |
851 "/ <primitive:'primitiveDotProduct' module: 'FloatArrayPlugin'> |
852 %{ |
852 %{ |
853 if (__isFloats(aFloatVector) |
853 if (__isFloats(aFloatVector) |
854 && (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
854 && (__ClassInstPtr(__qClass(self))->c_ninstvars == __mkSmallInteger(0)) |
855 && (__ClassInstPtr(__qClass(aFloatVector))->c_ninstvars == __mkSmallInteger(0))) { |
855 && (__ClassInstPtr(__qClass(aFloatVector))->c_ninstvars == __mkSmallInteger(0))) { |
856 INT __mySize = __floatArraySize(self); |
856 INT __mySize = __floatArraySize(self); |
857 INT __otherSize = __floatArraySize(aFloatVector); |
857 INT __otherSize = __floatArraySize(aFloatVector); |
858 float __result = 0.0; |
858 float __result = 0.0; |
859 |
859 |
860 if (__mySize == __otherSize) { |
860 if (__mySize == __otherSize) { |
861 if (__mySize > 0) { |
861 if (__mySize > 0) { |
862 float *__p1 = __FloatArrayInstPtr(self)->f_element; |
862 float *__p1 = __FloatArrayInstPtr(self)->f_element; |
863 float *__p2 = __FloatArrayInstPtr(aFloatVector)->f_element; |
863 float *__p2 = __FloatArrayInstPtr(aFloatVector)->f_element; |
864 INT __i; |
864 INT __i; |
865 /* how about inline-mmx-asm for this ... */ |
865 /* how about inline-mmx-asm for this ... */ |
866 for (__i=0; __i<__mySize; __i++) { |
866 for (__i=0; __i<__mySize; __i++) { |
867 __result += (__p1[__i] * __p2[__i]); |
867 __result += (__p1[__i] * __p2[__i]); |
868 } |
868 } |
869 } |
869 } |
870 RETURN (__MKFLOAT(__result)); |
870 RETURN (__MKFLOAT(__result)); |
871 } |
871 } |
872 } |
872 } |
873 %}. |
873 %}. |
874 ^ super dot:aFloatVector |
874 ^ super dot:aFloatVector |
875 |
875 |
876 " |
876 " |
877 |v| |
877 |v| |
878 |
878 |
879 v := #(2.0 2.0 1.0) asFloatArray. |
879 v := #(2.0 2.0 1.0) asFloatArray. |
880 v dot:v. |
880 v dot:v. |
881 " |
881 " |
882 " |
882 " |
883 |v1 v2| |
883 |v1 v2| |
884 |
884 |
885 v1 := FloatArray new:10000 withAll:2. |
885 v1 := FloatArray new:10000 withAll:2. |
886 v2 := FloatArray new:10000 withAll:3. |
886 v2 := FloatArray new:10000 withAll:3. |
887 Time millisecondsToRun:[ |
887 Time millisecondsToRun:[ |
888 10000 timesRepeat:[ |
888 10000 timesRepeat:[ |
889 v1 dot:v2. |
889 v1 dot:v2. |
890 ] |
890 ] |
891 ] |
891 ] |
892 " |
892 " |
893 |
893 |
894 "Created: / 29-05-2007 / 13:13:39 / cg" |
894 "Created: / 29-05-2007 / 13:13:39 / cg" |
895 ! ! |
895 ! ! |
896 |
896 |