1Float.Array(3) OCaml library Float.Array(3)
2
3
4
6 Float.Array - Float arrays with packed representation.
7
9 Module Float.Array
10
12 Module Array
13 : sig end
14
15
16 Float arrays with packed representation.
17
18
19
20
21
22 type t = floatarray
23
24
25 The type of float arrays with packed representation.
26
27
28 Since 4.08.0
29
30
31
32 val length : t -> int
33
34 Return the length (number of elements) of the given floatarray.
35
36
37
38 val get : t -> int -> float
39
40
41 get a n returns the element number n of floatarray a .
42
43
44 Raises Invalid_argument if n is outside the range 0 to (length a - 1) .
45
46
47
48 val set : t -> int -> float -> unit
49
50
51 set a n x modifies floatarray a in place, replacing element number n
52 with x .
53
54
55 Raises Invalid_argument if n is outside the range 0 to (length a - 1) .
56
57
58
59 val make : int -> float -> t
60
61
62 make n x returns a fresh floatarray of length n , initialized with x .
63
64
65 Raises Invalid_argument if n < 0 or n > Sys.max_floatarray_length .
66
67
68
69 val create : int -> t
70
71
72 create n returns a fresh floatarray of length n , with uninitialized
73 data.
74
75
76 Raises Invalid_argument if n < 0 or n > Sys.max_floatarray_length .
77
78
79
80 val init : int -> (int -> float) -> t
81
82
83 init n f returns a fresh floatarray of length n , with element number i
84 initialized to the result of f i . In other terms, init n f tabulates
85 the results of f applied to the integers 0 to n-1 .
86
87
88 Raises Invalid_argument if n < 0 or n > Sys.max_floatarray_length .
89
90
91
92 val append : t -> t -> t
93
94
95 append v1 v2 returns a fresh floatarray containing the concatenation of
96 the floatarrays v1 and v2 .
97
98
99 Raises Invalid_argument if length v1 + length v2 > Sys.max_floatar‐
100 ray_length .
101
102
103
104 val concat : t list -> t
105
106 Same as Float.Array.append , but concatenates a list of floatarrays.
107
108
109
110 val sub : t -> int -> int -> t
111
112
113 sub a pos len returns a fresh floatarray of length len , containing the
114 elements number pos to pos + len - 1 of floatarray a .
115
116
117 Raises Invalid_argument if pos and len do not designate a valid subar‐
118 ray of a ; that is, if pos < 0 , or len < 0 , or pos + len > length a .
119
120
121
122 val copy : t -> t
123
124
125 copy a returns a copy of a , that is, a fresh floatarray containing the
126 same elements as a .
127
128
129
130 val fill : t -> int -> int -> float -> unit
131
132
133 fill a pos len x modifies the floatarray a in place, storing x in ele‐
134 ments number pos to pos + len - 1 .
135
136
137 Raises Invalid_argument if pos and len do not designate a valid subar‐
138 ray of a .
139
140
141
142 val blit : t -> int -> t -> int -> int -> unit
143
144
145 blit src src_pos dst dst_pos len copies len elements from floatarray
146 src , starting at element number src_pos , to floatarray dst , starting
147 at element number dst_pos . It works correctly even if src and dst are
148 the same floatarray, and the source and destination chunks overlap.
149
150
151 Raises Invalid_argument if src_pos and len do not designate a valid
152 subarray of src , or if dst_pos and len do not designate a valid subar‐
153 ray of dst .
154
155
156
157 val to_list : t -> float list
158
159
160 to_list a returns the list of all the elements of a .
161
162
163
164 val of_list : float list -> t
165
166
167 of_list l returns a fresh floatarray containing the elements of l .
168
169
170 Raises Invalid_argument if the length of l is greater than
171 Sys.max_floatarray_length .
172
173
174
175
176 Iterators
177 val iter : (float -> unit) -> t -> unit
178
179
180 iter f a applies function f in turn to all the elements of a . It is
181 equivalent to f a.(0); f a.(1); ...; f a.(length a - 1); () .
182
183
184
185 val iteri : (int -> float -> unit) -> t -> unit
186
187 Same as Float.Array.iter , but the function is applied with the index
188 of the element as first argument, and the element itself as second ar‐
189 gument.
190
191
192
193 val map : (float -> float) -> t -> t
194
195
196 map f a applies function f to all the elements of a , and builds a
197 floatarray with the results returned by f .
198
199
200
201 val mapi : (int -> float -> float) -> t -> t
202
203 Same as Float.Array.map , but the function is applied to the index of
204 the element as first argument, and the element itself as second argu‐
205 ment.
206
207
208
209 val fold_left : ('a -> float -> 'a) -> 'a -> t -> 'a
210
211
212 fold_left f x init computes f (... (f (f x init.(0)) init.(1)) ...)
213 init.(n-1) , where n is the length of the floatarray init .
214
215
216
217 val fold_right : (float -> 'a -> 'a) -> t -> 'a -> 'a
218
219
220 fold_right f a init computes f a.(0) (f a.(1) ( ... (f a.(n-1) init)
221 ...)) , where n is the length of the floatarray a .
222
223
224
225
226 Iterators on two arrays
227 val iter2 : (float -> float -> unit) -> t -> t -> unit
228
229
230 Array.iter2 f a b applies function f to all the elements of a and b .
231
232
233 Raises Invalid_argument if the floatarrays are not the same size.
234
235
236
237 val map2 : (float -> float -> float) -> t -> t -> t
238
239
240 map2 f a b applies function f to all the elements of a and b , and
241 builds a floatarray with the results returned by f : [| f a.(0) b.(0);
242 ...; f a.(length a - 1) b.(length b - 1)|] .
243
244
245 Raises Invalid_argument if the floatarrays are not the same size.
246
247
248
249
250 Array scanning
251 val for_all : (float -> bool) -> t -> bool
252
253
254 for_all f [|a1; ...; an|] checks if all elements of the floatarray sat‐
255 isfy the predicate f . That is, it returns (f a1) && (f a2) && ... &&
256 (f an) .
257
258
259
260 val exists : (float -> bool) -> t -> bool
261
262
263 exists f [|a1; ...; an|] checks if at least one element of the floatar‐
264 ray satisfies the predicate f . That is, it returns (f a1) || (f a2) ||
265 ... || (f an) .
266
267
268
269 val mem : float -> t -> bool
270
271
272 mem a set is true if and only if there is an element of set that is
273 structurally equal to a , i.e. there is an x in set such that compare a
274 x = 0 .
275
276
277
278 val mem_ieee : float -> t -> bool
279
280 Same as Float.Array.mem , but uses IEEE equality instead of structural
281 equality.
282
283
284
285
286 Sorting
287 val sort : (float -> float -> int) -> t -> unit
288
289 Sort a floatarray in increasing order according to a comparison func‐
290 tion. The comparison function must return 0 if its arguments compare
291 as equal, a positive integer if the first is greater, and a negative
292 integer if the first is smaller (see below for a complete specifica‐
293 tion). For example, compare is a suitable comparison function. After
294 calling sort , the array is sorted in place in increasing order. sort
295 is guaranteed to run in constant heap space and (at most) logarithmic
296 stack space.
297
298 The current implementation uses Heap Sort. It runs in constant stack
299 space.
300
301 Specification of the comparison function: Let a be the floatarray and
302 cmp the comparison function. The following must be true for all x , y ,
303 z in a :
304
305 - cmp x y > 0 if and only if cmp y x < 0
306
307 - if cmp x y >= 0 and cmp y z >= 0 then cmp x z >= 0
308
309 When sort returns, a contains the same elements as before, reordered in
310 such a way that for all i and j valid indices of a :
311
312 - cmp a.(i) a.(j) >= 0 if and only if i >= j
313
314
315
316
317 val stable_sort : (float -> float -> int) -> t -> unit
318
319 Same as Float.Array.sort , but the sorting algorithm is stable (i.e.
320 elements that compare equal are kept in their original order) and not
321 guaranteed to run in constant heap space.
322
323 The current implementation uses Merge Sort. It uses a temporary
324 floatarray of length n/2 , where n is the length of the floatarray. It
325 is usually faster than the current implementation of Float.Array.sort .
326
327
328
329 val fast_sort : (float -> float -> int) -> t -> unit
330
331 Same as Float.Array.sort or Float.Array.stable_sort , whichever is
332 faster on typical input.
333
334
335
336
337 Float arrays and Sequences
338 val to_seq : t -> float Seq.t
339
340 Iterate on the floatarray, in increasing order. Modifications of the
341 floatarray during iteration will be reflected in the sequence.
342
343
344
345 val to_seqi : t -> (int * float) Seq.t
346
347 Iterate on the floatarray, in increasing order, yielding indices along
348 elements. Modifications of the floatarray during iteration will be re‐
349 flected in the sequence.
350
351
352
353 val of_seq : float Seq.t -> t
354
355 Create an array from the generator.
356
357
358
359 val map_to_array : (float -> 'a) -> t -> 'a array
360
361
362 map_to_array f a applies function f to all the elements of a , and
363 builds an array with the results returned by f : [| f a.(0); f a.(1);
364 ...; f a.(length a - 1) |] .
365
366
367
368 val map_from_array : ('a -> float) -> 'a array -> t
369
370
371 map_from_array f a applies function f to all the elements of a , and
372 builds a floatarray with the results returned by f .
373
374
375
376
377 Arrays and concurrency safety
378 Care must be taken when concurrently accessing float arrays from multi‐
379 ple domains: accessing an array will never crash a program, but unsyn‐
380 chronized accesses might yield surprising (non-sequentially-consistent)
381 results.
382
383
384 Atomicity
385 Every float array operation that accesses more than one array element
386 is not atomic. This includes iteration, scanning, sorting, splitting
387 and combining arrays.
388
389 For example, consider the following program:
390 let size = 100_000_000
391 let a = Float.Array.make size 1.
392 let update a f () =
393 Float.Array.iteri (fun i x -> Float.Array.set a i (f x)) a
394 let d1 = Domain.spawn (update a (fun x -> x +. 1.))
395 let d2 = Domain.spawn (update a (fun x -> 2. *. x +. 1.))
396 let () = Domain.join d1; Domain.join d2
397
398
399 After executing this code, each field of the float array a is either 2.
400 , 3. , 4. or 5. . If atomicity is required, then the user must im‐
401 plement their own synchronization (for example, using Mutex.t ).
402
403
404 Data races
405 If two domains only access disjoint parts of the array, then the ob‐
406 served behaviour is the equivalent to some sequential interleaving of
407 the operations from the two domains.
408
409 A data race is said to occur when two domains access the same array el‐
410 ement without synchronization and at least one of the accesses is a
411 write. In the absence of data races, the observed behaviour is equiva‐
412 lent to some sequential interleaving of the operations from different
413 domains.
414
415 Whenever possible, data races should be avoided by using synchroniza‐
416 tion to mediate the accesses to the array elements.
417
418 Indeed, in the presence of data races, programs will not crash but the
419 observed behaviour may not be equivalent to any sequential interleaving
420 of operations from different domains. Nevertheless, even in the pres‐
421 ence of data races, a read operation will return the value of some
422 prior write to that location with a few exceptions.
423
424
425 Tearing
426 Float arrays have two supplementary caveats in the presence of data
427 races.
428
429 First, the blit operation might copy an array byte-by-byte. Data races
430 between such a blit operation and another operation might produce sur‐
431 prising values due to tearing: partial writes interleaved with other
432 operations can create float values that would not exist with a sequen‐
433 tial execution.
434
435 For instance, at the end of
436 let zeros = Float.Array.make size 0.
437 let max_floats = Float.Array.make size Float.max_float
438 let res = Float.Array.copy zeros
439 let d1 = Domain.spawn (fun () -> Float.Array.blit zeros 0 res 0 size)
440 let d2 = Domain.spawn (fun () -> Float.Array.blit max_floats 0 res 0 size)
441 let () = Domain.join d1; Domain.join d2
442
443
444 the res float array might contain values that are neither 0. nor
445 max_float .
446
447 Second, on 32-bit architectures, getting or setting a field involves
448 two separate memory accesses. In the presence of data races, the user
449 may observe tearing on any operation.
450
451OCamldoc 2023-07-20 Float.Array(3)