eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'FloatArray':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: FloatArray


Inheritance:

   Object
   |
   +--Collection
      |
      +--SequenceableCollection
         |
         +--ArrayedCollection
            |
            +--UninterpretedBytes
               |
               +--AbstractNumberVector
                  |
                  +--UnboxedFloatArray
                     |
                     +--FloatArray

Package:
stx:libbasic
Category:
Collections-Arrayed
Version:
rev: 1.90 date: 2023/06/12 08:54:12
user: cg
file: FloatArray.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


FloatArrays store single precision floats (and nothing else).

They have been added to support heavy duty number crunching and
data exchange with openGL frameworks and other mass data libraries.
See documentation in DoubleArray for more information.

FloatArrays can be used as literals i.e. you can enter FloatArray-constants as:
    #f32( element1 element2 .... elementN )
for example:
    #f32(1 2.0 3 4.0)

Aliased as Float32Array.

[memory requirements:]
    OBJ-HEADER + (size * float-size)

[complexity:]
    see Array

copyright

COPYRIGHT (c) 1993 by Claus Gittinger All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

queries
o  elementByteSize
for bit-like containers, return the number of bytes stored per element.
Here, 4 is returned

o  epsilon
return the maximum relative spacing of my elements
(i.e. the value-delta of the least significant bit)
according to ISO C standard;
Ada, C, C++ and Python language constants;
Mathematica, MATLAB and Octave; and various textbooks
see https://en.wikipedia.org/wiki/Machine_epsilon

o  fmax
return the largest value that instances of me can represent

o  fmin
return the smallest normalized non-zero value that instances of me can hold

o  literalTokenPrefix

o  precision
answer the precision (the number of bits in the mantissa) of my elements (in bits)
This is an IEEE float, where only the fraction from the normalized mantissa is stored
and so there is a hidden bit and the mantissa is actually represented by 24 binary digits
(although only 23 are needed in the binary representation)
the hidden bit is included here


Instance protocol:

copying
o  clone
Return a clone-copy of the receiver

Usage example(s):

     |f1|

     f1 := FloatArray withAll:#(1 2 3 4 5).
     f1 clone

o  copyFrom: start to: stop
return a partial copy of the receiver

Usage example(s):

     |f1 f2|

     f1 := FloatArray withAll:#(1 2 3 4 5 6).
     f2 := f1 copyFrom:3 to:5.
     f2

o  replaceFrom: start to: stop with: aCollection startingAt: replStart
replace elements in the receiver between index start and stop,
with elements taken from aCollection starting at repStart.
Return the receiver.

Usage example(s):

     |f1 f2|

     f1 := (100 to:105) asFloatArray.
     f2 := #(1 2 3 4 5 6 7 8) asFloatArray.
     f1 replaceFrom:1 to:3 with:f2 startingAt:3.
     self assert:(f1 = #f32( 3 4 5 103 104 105) )

Usage example(s):

     |f1 f2|

     f1 := (100 to:105) asFloatArray.
     f2 := #(1 2 3 4 5 6 7 8) asSignedWordArray.
     f1 replaceFrom:1 to:3 with:f2 startingAt:3.
     self assert:(f1 = #f32( 3 4 5 103 104 105) )

Usage example(s):

     |f1 f2|

     f1 := (100 to:107) asFloatArray.
     f2 := #(1 2 3 4 5 6 7 8) asSignedWordArray.
     f1 replaceFrom:3 to:6 with:f2 startingAt:2.
     self assert:(f1 = #f32(100 101 2 3 4 5 106 107) )

Usage example(s):

     |f1 f2|

     f1 := (100 to:105) asFloatArray.
     f2 := #(1 2 3 4 5 6 7 8) asSignedWordArray.
     f1 replaceFrom:1 to:6 with:f2 startingAt:1.
     self assert:(f1 = #f32(1 2 3 4 5 6) )

Usage example(s):

     |d s|
     d := FloatArray new:1000.
     s := (1 to:1000) asFloatArray.
     (Time toRun:[
        100 timesRepeat:[ d replaceFrom:1 to:1000 with:s startingAt:1 ]
     ]) / 100.

Usage example(s):

     |d s|
     d := FloatArray new:1000.
     s := (1 to:1000) asSignedWordArray.
     (Time toRun:[
        100 timesRepeat:[ d replaceFrom:1 to:1000 with:s startingAt:1 ]
     ]) / 100.

o  replaceFrom: start to: stop with: aCollection startingAt: replStart scale: multiplier
replace elements in the receiver between index start and stop,
with scaled elements taken from replacementCollection starting at repStart.
Scaling is done by multiplying each element from aCollection by multiplier.
Use this to convert 16bit sample data to normalized float values in the 0..1 range
(eg. for audio sample processing, you'd use a scale of 1/32768 to scale shorts)
Return the receiver.

Usage example(s):

     |f1 f2|

     f1 := (100 to:105) asFloatArray.
     f2 := #(1 2 3 4 5 6 7 8) asFloatArray.
     f1 replaceFrom:1 to:3 with:f2 startingAt:3 scale:2.
     self assert:(f1 = #f32( 6 8 10 103 104 105) )

Usage example(s):

     |f1 f2|

     f1 := (100 to:105) asFloatArray.
     f2 := #(1 2 3 4 5 6 7 8) asSignedWordArray.
     f1 replaceFrom:1 to:3 with:f2 startingAt:3 scale:3.
     self assert:(f1 = #f32( 9 12 15 103 104 105) )

Usage example(s):

     |f1 f2|

     f1 := (100 to:105) asFloatArray.
     f2 := #(1 2 3 4 5 6 7 8) asArray.
     f1 replaceFrom:1 to:3 with:f2 startingAt:3 scale:3.
     self assert:(f1 = #f32( 9 12 15 103 104 105) )

Usage example(s):

     |d s|
     d := FloatArray new:1000.
     s := (1 to:1000) asFloatArray.
     (Time toRun:[
        100 timesRepeat:[ d replaceFrom:1 to:1000 with:s startingAt:1 scale:2]
     ]) / 100.

Usage example(s):

     |d s|
     d := FloatArray new:1000.
     s := (1 to:1000) asSignedWordArray.
     (Time toRun:[
        100 timesRepeat:[ d replaceFrom:1 to:1000 with:s startingAt:1 scale:2]
     ]) / 100.

Usage example(s):

     |d s|
     d := FloatArray new:1000.
     s := (1 to:1000) asArray.
     (Time toRun:[
        100 timesRepeat:[ d replaceFrom:1 to:1000 with:s startingAt:1 scale:2 ]
     ]) / 100.

destructive arithmetic support
o  primAbs
destructive absolute value of each element;
does not check for immutability: only use internally after cloning

Usage example(s):

     |d s|
     d := (0 to:1 by:0.0001) asFloatArray.
     (Time toRun:[
        100 timesRepeat:[ d primAbs ]
     ]) / 100. 2400ns 2380ns 5µs 5µs

o  primAddArray: floatArray
add the vector argument into the receiver (destructive).
The argument must be another vector of the same or larger size;
if the arguments size is larger, only the first n (=self size) elements are added in.
Does not check for immutability: only use internally after cloning

o  primAddScalar: aScalar
add the scalar argument into the receiver (destructive).
does not check for immutability: only use internally after cloning

o  primDivideArray: floatArray
divide the vector argument into the receiver (destructive).
The argument must be another vector.
does not check for immutability: only use internally after cloning

o  primMulArray: floatArray
multiply the vector argument into the receiver (destructive).
The argument must be another vector.
does not check for immutability: only use internally after cloning

o  primMulScalar: aScalar
multiply the scalar argument into the receiver (destructive).
does not check for immutability: only use internally after cloning

o  primNegated
destructive negative value of each element.
does not check for immutability: only use internally after cloning

Usage example(s):

     |d s|
     d := (0 to:1 by:0.0001) asFloatArray.
     (Time toRun:[
	100 timesRepeat:[ d primNegated ]
     ]) / 100. 1730ns 1740ns 2980ns 3µs  2990ns

o  primSubtractArray: floatArray
subtract the vector argument from the receiver (destructive).
The argument must be another vector.
does not check for immutability: only use internally after cloning

filling & replacing
o  from: startIndex to: endIndex put: aValue
replace all elements of the collection by the argument, aNumber.
Return the receiver.
The argument, aValue must be a number which can be converted to a float.
Notice: This operation modifies the receiver, NOT a copy;
therefore the change may affect all others referencing the receiver.

Usage example(s):

     |f|

     f := FloatArray new:100.
     f from:2 to:5 put:1.
     f from:90 to:99 put:1.
     f from:1 to:100 put:2.
     f

Usage example(s):

     |f t|

     f := FloatArray new:100000.
     t := Time toRun:[
	    10000 timesRepeat:[ f from:2 to:99999 put:1.0 ].
	  ].
     Transcript showCR: e'time to fill part: {t/10000}'

Usage example(s):

     |f t|

     f := FloatArray new:100000.
     t := Time toRun:[
	    10000 timesRepeat:[ f from:2 to:99999 put:0.0 ].
	  ].
     Transcript showCR: e'time to fill part: {t/10000}'

image operations
o  convoluteWith: kernel kWidth: kW kHeight: kH scale: scaleArg width: imgW height: imgH into: destArray
will be replaced by a faster version, if heavily used

Usage example(s):

     |img kernel cOut|

     img := #f32( 1.0  0.0  0.0  0.0
		  0.0  1.0  0.0  0.0
		  0.0  0.0  1.0  0.0
		  0.0  0.0  0.0  1.0
		).
     kernel := #f32(
		  0.11 0.11 0.11
		  0.11 0.11 0.11
		  0.11 0.11 0.11
	       ).
     cOut := img convoluteWith:kernel
	 kWidth:3 kHeight:3
	 width:4 height:4
	 into:(FloatArray new:(2*2)).

queries
o  defaultElement

o  minMax
return a Tuple holding the smallest and largest element;
redefined for speed

Usage example(s):

     |f1|

     f1 := (1 to:10000) asFloatArray.
     Time millisecondsToRun:[ 1000 timesRepeat:[ f1 minMax ] ]

Usage example(s):

     |f1|

     f1 := FloatArray withAll:#(1 2 3 4 5).
     f1 minMax

Usage example(s):

     |f1|

     f1 := FloatArray withAll:#(1 2 3 4).
     f1 minMax

Usage example(s):

     |f1|

     f1 := FloatArray withAll:#(5 4 3 2 1).
     f1 minMax

testing
o  isFloat32Array
return true if the receiver has float32 elements

vector arithmetic
o  dot: aFloatVector
Return the dot product of the receiver and the argument.
Raises an error, if the argument is not of the same size as the receiver.

Usage example(s):

     |v1 v2|

     v1 := Array new:10000 withAll:2.
     v2 := Array new:10000 withAll:3.
     Time millisecondsToRun:[
	10000 timesRepeat:[
	  v1 dot:v2.
	]
     ]

Usage example(s):

     |v1 v2|

     v1 := FloatArray new:10000 withAll:2.
     v2 := FloatArray new:10000 withAll:3.
     Time millisecondsToRun:[
	10000 timesRepeat:[
	  v1 dot:v2.
	]
     ]

Usage example(s):

     |v1 v2|
     v1 := #(2.0 2.0 1.0) asFloatArray.
     v2 := #(2.0 2.0 1.0 0.0) asDoubleArray.
     v1 dot:v2.

o  esum
Return the (double) sum of the elements.
Reduces accumulated rounding errors.
This is an experimental algorithm

Usage example(s):

here, sum and esum both deliver the same result
     |v|
     v := #(2.0 2.0 1.0 1.0) asFloatArray.
     v sum.
     v esum.

Usage example(s):

here, sum looses and delivers a wrong result
     (the first 1.0 is lost due to limited precision)

     |v|
     v := #(1e38 1.0 -1e38 1.0) asFloatArray.
     v sum.
     v esum.

o  hornerMultiplyAndAdd: x
primitive support for horner's-method computation of polynomials.
The vector is interpreted as providing the factors for a polynomial,
an*x^n + (an-1)*x^(n-1) + ... + a2(x) + a1
where the ai are the elements of the Array.
The highest rank factor is at the first position, the 0-rank constant at last.
This is inlined c-code, which may get compiled to fast machine code,
using multiply-and-add or vector instructions, if the CPU/Compiler support them.

o  sum
Return the (double) sum of the elements.
May suffer from accumulated rounding error


Examples:


    |vec|

    vec := FloatArray new:4.
    vec size.
    vec at:1.
    vec at:2.
    vec at:3.
    vec at:4.
    vec at:1 put:(1).
    vec at:2 put:(2).
    vec at:4 put:(4).
    vec


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sun, 26 May 2024 11:03:51 GMT