FloatArray.st
branchjv
changeset 18120 e3a375d5f6a8
parent 18017 7fef9e17913f
parent 17198 7518cd20d9d3
child 18608 7d521f25267c
equal deleted inserted replaced
18119:cb7a12afe736 18120:e3a375d5f6a8
    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"
   957     "Modified (comment): / 07-10-2011 / 13:03:30 / cg"
   831     "Modified (comment): / 07-10-2011 / 13:03:30 / cg"
   958 !
   832 !
   959 
   833 
   960 numFloats
   834 numFloats
   961     ^ self size
   835     ^ self size
   962 !
       
   963 
       
   964 squaredLength
       
   965     "Return the squared length of the receiver interpreted as vector"
       
   966 
       
   967     ^ self dot: self
       
   968 ! !
   836 ! !
   969 
   837 
   970 !FloatArray methodsFor:'vector arithmetic'!
   838 !FloatArray methodsFor:'vector arithmetic'!
   971 
   839 
   972 dot: aFloatVector
   840 dot: aFloatVector
   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