For Gauche 0.9.6


Next: , Previous: , Up: Library modules - Gauche extensions   [Contents][Index]

9.35 gauche.uvector - Uniform vectors

Module: gauche.uvector

Provides vectors whose elements are of the same numeric type, as defined in SRFI-4 (SRFI-4).

Gauche’s implementation is a superset of SRFI-4 in a few ways:

There are some advantages of using SRFI-4 vectors over normal (heterogeneous) vectors. It may be more compact than the normal vectors. Some operations (especially Gauche’s extension of vector arithmetic operations) can bypass type check and conversion of individual elements, thus be more efficient. And it is much easier and efficient to communicate with external libraries that require homogeneous array of numbers; for example, OpenGL binding of Gauche uses SRFI-4 vectors extensively.

The following eleven types of vectors are defined.

s8vector

Elements are exact integers in the range between -2^7 and 2^7-1

u8vector

Elements are exact integers in the range between 0 and 2^8-1

s16vector

Elements are exact integers in the range between -2^15 and 2^15-1

u16vector

Elements are exact integers in the range between 0 and 2^16-1

s32vector

Elements are exact integers in the range between -2^31 and 2^31-1

u32vector

Elements are exact integers in the range between 0 and 2^32-1

s64vector

Elements are exact integers in the range between -2^63 and 2^63-1

u64vector

Elements are exact integers in the range between 0 and 2^64-1

f16vector

Elements are inexact real numbers representable in 16bits float (a.k.a half float)

f32vector

Elements are inexact real numbers representable in the float of C compiler that compiles Gauche. Usually it is a single precision IEEE floating point number.

f64vector

Elements are inexact real numbers representable in the double of C compiler that compiles Gauche. Usually it is a double precision IEEE floating point number.

When you try to store a number out of the range of the vector type, an error is signaled by default. However, some procedures take an optional argument clamp that specifies alternative behavior in such a case. Clamp argument may take one of the following values.

#f

Default behavior (signals an error).

high

Clamps high bound; i.e. if the value to be stored is beyond the higher bound of the range, the maximum value is stored instead.

low

Clamps low bound; i.e. if the value to be stored is below the lower bound of the range, the minimum value is stored instead.

both

Clamps both sides; does both high and low.

(list->u8vector '(-1))         ⇒ error
(list->u8vector '(-1) 'low)    ⇒ #u8(0)
(list->u8vector '(-1) 'high)   ⇒ error
(list->u8vector '(3000) 'high) ⇒ #u8(255)
(list->u8vector '(-100 20 300) 'both) ⇒ #u8(0 20 255)

In the following description, TAG can be replaced for any of s8, u8, s16, u16, s32, u32, s64, u64, f16, f32, f64.


Next: , Previous: , Up: Uniform vectors   [Contents][Index]

9.35.1 Uvector basic operations

Builtin Class: <TAGvector>

{gauche.uvector} A class for TAGvector. It inherits <sequence>.

Reader Syntax: #TAG(n …)

Denotes a literal homogeneous vector.

#s8(3 -2 4)
#u32(4154 88357 2 323)
#f32(3.14 0.554525 -3.342)
Function: TAGvector? obj

[SRFI-4] {gauche.uvector} Returns #t iff obj is a TAGvector, #f otherwise.

Function: uvector? obj

{gauche.uvector} Returns #t iff obj is of any uniform vector type.

Function: TAGvector x

[SRFI-4] {gauche.uvector} Constructs TAGvector whose elements are numbers x …. The numbers must be exact integer for exact integer vectors, and in the valid range of the vector.

(s8vector 1 2 3) ⇒ #s8(1 2 3)
Function: make-TAGvector len :optional fill

[SRFI-4] {gauche.uvector} Constructs a TAGvector of length len. The elements are initialized by a number fill. For exact integer vectors, fill must be an exact integer and in the valid range. If fill is omitted, the content of the vector is undefined.

(make-u8vector 4 0) ⇒ #u8(0 0 0 0)
Function: make-uvector class len :optional fill

{gauche.uvector} This is a Gauche extension; instead of using separate constructor for each uvector type, you can pass the class of desired uvector.

(make-uvector <u8vector> 3)    ⇒ #u8(0 0 0)
(make-uvector <s8vector> 5 -1) ⇒ #s8(-1 -1 -1 -1 -1)
Function: TAGvector-length vec

[SRFI-4] {gauche.uvector} Returns the length of the TAGvector vec.

Note that the generic function size-of can be used to obtain the length of vec as well, if you import gauche.collection (see Collection framework).

(s16vector-length '#s16(111 222 333)) ⇒ 3

(use gauche.collection)
(size-of '#s16(111 222 333)) ⇒ 3
Function: uvector-length uvector

{gauche.uvector} This is a generic version of TAGvector-length; you can pass any instance of uniform vector, and it returns the number of its elements.

Function: uvector-size uvector :optional start end

{gauche.uvector} This function can be applied to any type of uniform vectors, and returns the raw size of the uvector in number of octets.

When start and/or end is/are given, the size of data between those indices are calculated. The special value -1 for end indicates the end of the vector. The returned value matches the number of octets to be written out by (write-uvector uvector port start end).

(Do not confuse this with uvector-length, which returns the number of elements.)

(uvector-size '#u8(1 2 3))        ⇒ 3
(uvector-size '#u64(1 2 3))       ⇒ 24

(uvector-size '#u32(0 1 2 3) 2)   ⇒ 8
(uvector-size '#u32(0 1 2 3) 0 1) ⇒ 4
Function: uvector-class-element-size class

{gauche.uvector} Returns the size of an element of a uvector of the given class, in bytes. An error is raised when class is not a uvector class.

(uvector-class-element-size <u8vector>)  ⇒ 1
(uvector-class-element-size <s64vector>) ⇒ 8
Function: TAGvector-ref vec k :optional fallback

[SRFI-4+] {gauche.uvector} Returns the k-th element of TAGvector vec.

If the index k is out of the valid range, an error is signaled unless an optional argument fallback is given; in that case, fallback is returned.

Note that the generic function ref can be used as well, if you import gauche.collection.

(u16vector-ref '#u16(111 222 333) 1) ⇒ 222

(use gauche.collection)
(ref '#u16(111 222 333) 1) ⇒ 222
Function: uvector-ref vec k :optional fallback

{gauche.uvector} Generic version of TAGvector-ref. It can take any kind of uniform vector to vec, and returns its k-th element. If the index k is out of the valid range, an error is signaled unless an optional argument fallback is given; in that case, fallback is returned.

This is handy to write a generic code that works on any kind of uniform vector, but this is slower than the specific versions. Gauche’s compiler recognizes the specific versions of referencer and generate very efficient code for them, while this generic version becomes a normal procedure call. In inner-loop it can make a big difference.

(setter uvector-ref) is uvector-set!.

Function: TAGvector-set! vec k n :optional clamp

[SRFI-4+] {gauche.uvector} Sets a number n to the k-th element of TAGvector vec. Optional clamp argument specifies the behavior when n is out of valid range. Default is to signal an error.

Note that the setter of the generic function ref can be used as well, if you import gauche.collection.

(let ((v (s32vector -439 852 8933)))
  (s32vector-set! v 1 4)
  v)
 ⇒ #s32vector(-439 4 8933)

(use gauche.collection)
(let ((v (s32vector -439 852 8933)))
  (set! (ref v 1) 4)
  v)
 ⇒ #s32vector(-439 4 8933)
Function: uvector-set! vec k val

{gauche.uvector} Generic version of TAGvector-set!. It can handle any kind of uniform vectors, but a bit slower than the specific versions.

Function: TAGvector-fill! vec fill :optional start end

{gauche.uvector} Stores fill in every element of vec, ranging from start to end of vec, if they are given.

Function: TAGvector=? vec1 vec2

[SRFI-66] {gauche.uvector} Both arguments must be a TAGvector. Returns #t if vec1 and vec2 are equal to each other, #f otherwise.

Note that you can compare uvectors with equal? in Gauche. These are provided because SRFI-66 defines u8vector=?. You can also use them to indicate arguments are vectors of the specific type.

Function: TAGvector-compare vec1 vec2

[SRFI-66] {gauche.uvector} Both arguments must be a TAGvector. Returns -1 if vec1 is smaller than vec2, 0 if both are equal to each other, and 1 if vec1 is greater than vec2.

Shorter vector is smaller than longer vectors. If the lengths of both vectors are the same, elements are compared from left to right.

Note that you can compare uvectors with compare in Gauche. These are provided because SRFI-66 defines u8vector-compare. You can also use them to indicate arguments are vectors of the specific type.

Function: TAGvector-copy vec :optional start end

{gauche.uvector} Copies the srfi-4 vector vec. If start and/or end are given, they limit the range of vec to be copied.

(u8vector-copy '#u8(1 2 3 4))     ⇒ #u8(1 2 3 4)
(u8vector-copy '#u8(1 2 3 4) 2)   ⇒ #u8(3 4)
(u8vector-copy '#u8(1 2 3 4) 1 3) ⇒ #u8(2 3)
Function: uvector-copy vec :optional start end

{gauche.uvector} This is a generic version of TAGvector-copy. You can give any type of uvector to vec, and get its copy (or copy of its part, depending on start/end argument).

Function: TAGvector-copy! target tstart source :optional sstart send

{gauche.uvector} Both target and source must be TAGvectors, and target must be mutable. This procedure copies the elements of source, beginning from index sstart (inclusive) and up to send, into target, beginning from index tstart. sstart and send may be omitted, and in that case 0 and the length of source are assumed, respectively.

(let ((target (u8vector 0 1 2 3 4 5 6)))
  (u8vector-copy! target 2 '#u8(10 11 12 13 14) 1 4)
  target)
 ⇒ #u8(0 1 11 12 13 6)

If the number of elements in the source vector between sstart and send is larger than the target vector beginning from tstart, the excess elements are silently discarded.

It is ok to pass the same vector to target and source; it always works even if the regions of source and destination are overlapping.

Note: This procedure used to take just two uniform vectors, target and source, and just copies contents of source to target. Both vectors had to be the same type and same length. The API is revised to the current form to make it parallel with string-copy! (SRFI-13) and vector-copy! (R7RS,SRFI-133). The old interface is still supported for the backward compatibility, but it is deprecated and will be gone in the future releases.

Also note that SRFI-66 provides uvector-copy! with different argument order (see Octet vectors).

Function: TAGvector-multi-copy! target tstart tstride source :optional sstart ssize sstride count

{gauche.uvector} This procedure allows different parts of the source uvector source into various parts of the target uvector target, all at once.

When ssize is omitted or zero, this procedure does the following:

;; For each i from 0 to count:
(TAGvector-copy! target (+ tstart (* i tstride))
                 source sstart)

That is, it copies the content of source (offsetted by sstart, which defaults to 0) into the target repeatedly, advancing index with tstride. If either the target index reaches the end or count copies are made, the procedure returns. See the example:

(define t (make-u8vector 10 0))
(u8vector-multi-copy! t 0 4 '#u8(1 2 3))

t ⇒ #u8(1 2 3 0 1 2 3 0 1 2)

If ssize is given and positive, the source is also splitted as follows:

;; For each i from 0 to count:
(TAGvector-copy! target (+ tstart (* i tstride))
                 source (+ sstart (* i sstride))
                        (+ sstart (* i sstride) ssize))

That is, each ssize slice from source, is copied into target, advaincing source index by sstride and the destination index by dstride. In this case, sstride defaults to ssize if omitted.

(define t (make-u8vector 12 0))
(u8vector-multi-copy! t 0 4 '#u8(1 2 3 4 5 6 7 8 9) 0 3)

t ⇒ #u8(1 2 3 0 4 5 6 0 7 8 9 0)

The operation ends when either count slices are copied, or destination index or source index reaches the end.

Hint: If you want to copy a part of the source vector repeatedly (instead of to its end), you can specify 0 to sstride:

(define t (make-u8vector 12 0))
(u8vector-multi-copy! t 0 4 '#u8(1 2 3 4 5 6 7 8 9) 2 4 0)

t ⇒ #u8(3 4 5 6 3 4 5 6 3 4 5 6)

Using collection and sequence framework, you can perform various operations on the homogeneous vectors.

(use gauche.collection)
(use gauche.sequence)

(fold + 0 '#s32(1 2 3 4)) ⇒ 10

(map-to <f32vector> * '#f32(3.2 1.1 4.3) '#f32(-4.3 2.2 9.4))
  ⇒ #f32(-13.760001 2.420000 40.420002)

(subseq #u32(1 4 3 4 5) 2 4) ⇒ #u32(3 4)
Function: uvector-copy! target tstart source :optional sstart send

{gauche.uvector} This is a generic version of TAGvector-copy!. The destination target and the source source can be any type of uniform vectors, and they don’t need to match. The copy is done bit-by-bit. So if you copy to a different type of uvector, the result depends on how the numbers are represented internally. This is mainly to manipulate binary data.

Tstart is interpreted according to the type of target, and sstart and send are interpreted according to the type of source.

(rlet1 v (make-u8vector 6 0)
  (uvector-copy! v 1 '#u32(0 #x01020304 0) 1 2))
 ⇒ #u8(0 1 2 3 4 0) or #u8(0 4 3 2 1 0)
Function: TAGvector-append vec …

{gauche.uvector} All arguments must be TAGvectors. Returns a fresh vector whose contents are concatenation of the given vectors.

(u8vector-append '#u8(1 2 3) '#u8(4 5) '#u8() '#u8(6 7 8))
  ⇒ #u8(1 2 3 4 5 6 7 8)
Function: uvector-binary-search uvector key :optional start end skip rounding

{gauche.uvector} The uvector must contain values in increasing order. This procedure finds the index of an element that is equal to key, using binary search. If such element can’t be found, #f is returned.

(uvector-binary-search '#u8(0 5 19 32 58 96) 32)
  ⇒ 3

(uvector-binary-search '#u8(0 5 19 32 58 96) 33)
  ⇒ #f

The optional start and end arguments limits the portion of uvector to search; start specifies starting index (inclusive) and end specifies ending index (exclusive). Passing #f indicates the default value (0 for start, the length of the vector for end). The returned index is the actual index of the vector, but the elements outside of start-end range don’t need to be sorted.

(uvector-binary-search '#u8(99 99 19 32 58 99) 32 2 5)
  ⇒ 3

(uvector-binary-search '#u8(99 99 19 32 58 99) 99 2 5)
  ⇒ #f

The optional skip argument must be a nonnegative exact integer or #f. If it is a positive integer, the number of elements after every key in the uvector is ignored. For example, if skip is 2 and uvector is #u8(3 100 101 5 102 103 13 104 105), only 3, 5 and 13 are subject to seach, and elements inbetween are ignored. This allows the caller to store payload, or associated value to each key, in the uvector itself. If skip is positive integer, the length of the searched portion of uvector must be a multiple of the record size (skip+1).

(uvector-binary-search '#u8(3 100 101 5 102 103 13 104 105) 13 #f #f 2)
  ⇒ 6

(uvector-binary-search '#u8(3 100 101 5 102 103 13 104) 13 #f #f 2)
  ⇒ ; Error: uvector size (8) isn’t multiple of record size (3)

Finally, rounding argument adjusts the behavior when the exact match isn’t found. It can be either one of the following values:

#f

This is the default. The procedure seaches the element that is equal to key, and returns #f if such element isn’t found.

a symbol floor

When the exact match isn’t found, the procedure returns an index of the element that’s closest to but not greater than key. If key is smaller than all the elements, #f is returned.

a symbol ceiling

When the exact match isn’t found, the procedure returns an index of the element that’s closest to but not smaller than key. If key is greater than all the elements, #f is returned.

(uvector-binary-search '#u32(1 10 100 1000 10000) 3757)
  ⇒ #f

(uvector-binary-search '#u32(1 10 100 1000 10000) 3757 #f #f #f 'floor)
  ⇒ 3

(uvector-binary-search '#u32(1 10 100 1000 10000) 3757 #f #f #f 'ceiling)
  ⇒ 4

Note: SRFI-133 has vector-binary-search, which is quite similar to this procedure (see Vector library) but it requires comparison procedure, for it needs to compare general Scheme values. And it does not support skip and rounding arguments.


Next: , Previous: , Up: Uniform vectors   [Contents][Index]

9.35.2 Uvector conversion operations

Function: TAGvector->list vec :optional start end

[SRFI-4+] {gauche.uvector} Converts TAGvector vec to a list. If start and/or end are given, they limit the range of vec to be extracted.

Note that the generic function coerce-to can be used as well, if you import gauche.collection.

(u32vector->list '#u32(9 2 5)) ⇒ (9 2 5)

(use gauche.collection)
(coerce-to <list> '#u32(9 2 5)) ⇒ (9 2 5)
Function: TAGvector->vector vec :optional start end

{gauche.uvector} Converts TAGvector vec to a vector. If start and/or end are given, they limit the range of vec to be copied.

Note that the generic function coerce-to can be used as well, if you import gauche.collection.

(f32vector->vector '#f32(9.3 2.2 5.5))   ⇒ #(9.3 2.2 5.5)
(f32vector->vector '#f32(9.3 2.2 5.5) 2) ⇒ #(5.5)

(use gauche.collection)
(coerce-to <vector> '#f32(9.3 2.2 5.5)) ⇒ #(9.3 2.2 5.5)
Function: list->TAGvector list :optional clamp

[SRFI-4+] {gauche.uvector} Converts a list list to a TAGvector. Optional argument clamp specifies the behavior when the element of list is out of the valid range.

Note that the generic function coerce-to can be used as well, if you import gauche.collection.

(list->s64vector '(9 2 5)) ⇒ #s64(9 2 5)

(use gauche.collection)
(coerce-to <s64vector> '(9 2 5)) ⇒ #s64(9 2 5)
Function: vector->TAGvector vec :optional start end clamp

{gauche.uvector} Converts a vector vec to a TAGvector. If start and/or end are given, they limit the range of vec to be copied. Optional argument clamp specifies the behavior when the element of vec is out of the valid range.

Note that the generic function coerce-to can be used as well, if you import gauche.collection.

(vector->f64vector '#(3.1 5.4 3.2)) ⇒ #f64(3.1 5.4 3.2)

(use gauche.collection)
(coerce-to <f64vector> '#(3.1 5.4 3.2)) ⇒ #f64(3.1 5.4 3.2)
Function: string->s8vector string :optional start end immutable?
Function: string->u8vector string :optional start end immutable?

{gauche.uvector} Returns an s8vector or u8vector whose byte sequence is the same as the internal representation of the given string. Optional range arguments start and end specifies the character position (not the byte position) inside string to be converted.

By default, the content of the string is copied to a newly created mutable uvector. However, if a true value is given to the optional immutable? argument, the result is an immutable uvector, and it may avoid copying the string body (note that in Gauche, the body of string is immutable; string-set! creates a new body, so changing the original string won’t affect the uvector created by string->u8vector with immutable? flag.)

These procedures are useful when you want to access byte sequence of the string randomly.

(string->u8vector "abc") ⇒ #u8(97 98 99)

(string->u8vector "very large string .... " 0 -1 #t)
  ⇒ #u8(...)  ; immutable, sharing content with the original string
Function: string->s8vector! target tstart string :optional start end
Function: string->u8vector! target tstart string :optional start end

{gauche.uvector} Target must be an s8vector or a u8vector, respectively. Target must be mutable. Like copies the raw byte representation of string into target beginning from index tstart.

Returns target.

(let ((target (make-u8vector 10 0)))
  (string->u8vector! target 3 "abcde"))
 ⇒ #u8(0 0 0 97 98 99 100 101 0 0)
Function: s8vector->string vec :optional start end terminator
Function: u8vector->string vec :optional start end terminator

{gauche.uvector} Converts a byte sequence in s8vector or u8vector to a string that has the same byte sequence. Optional range arguments start and end specifies the byte position in vec to be converted.

The optional terminator argument can be an exact integer or #f (default). If it is an exact integer, and it appears in vec, the string terminates right before it. For example, you can give 0 as terminator to read a NUL-terminated string from a buffer.

(u8vector->string '#u8(65 66 0 67 68) 0 5)   ⇒ "AB\0CD"
(u8vector->string '#u8(65 66 0 67 68) 0 5 0) ⇒ "AB"

Note that these procedure may result an incomplete string if vec contains a byte sequence invalid as the internal encoding of the string.

Function: string->s32vector string :optional start end
Function: string->u32vector string :optional start end

{gauche.uvector} Returns an s32vector or u32vector whose elements are the internal codes of the characters in the string. Optional range arguments start and end specifies the character position inside string to be converted.

These procedures are useful when you want to access the characters in the string randomly.

Function: string->s32vector! target tstart string :optional start end
Function: string->u32vector! target tstart string :optional start end

{gauche.uvector} Target must be a mutable s32vector or u32vector, respectively. Fill the target from position tstart with the codepoint of each character of string, until either string is exhausted or target is filled to the end.

Optional range arguments start and end specifies the character position inside string to be considered.

Function: s32vector->string vec :optional start end terminator
Function: u32vector->string vec :optional start end terminator

{gauche.uvector} Without start and end, these procedures work like this:

(lambda (vec) (map-to <string> integer->char vec)))

Optional range arguments start and end limits the range of conversion between them.

The optional terminator argument must be an exact integer or #f (default). If an integer is given, and the integer is fonud in the input, the output string terminates right before it.

(u32vector->string '#u32(65 66 0 67 68) 0 5 0) ⇒ "AB"
Function: uvector-alias uvector-class vec :optional start end

{gauche.uvector} This procedure creates an uvector of class uvector-class that shares the storage of the given uniform vector vec. If optional start and end arguments are given, only the specified range of vec is used for the new vector. Since the storage is shared, modification of the original vector can be seen from the new vector, or vice versa.

The class uvector-class must be either one of the uniform vector class, but is not necessary match the class of the source vector vec. In such case, the new vector looks at the same region of vec’s memory, but interprets it differently. For example, the following code determines whether Gauche is running on big-endian or little-endian machine:

(let ((u8v (uvector-alias <u8vector> #u32(1))))
  (if (zero? (u8vector-ref u8v 0))
      'big-endian
      'little-endian))

If the uvector-class is other than s8vector or u8vector, the region the new vector points has to meet the alignment requirement. You can assume the beginning of the source vector is aligned suitable for any uniform vectors. So, for example, if you’re creating u32vector from u8vector, the start and end must be multiple of 4 (or, if they’re omitted, the length of the original u8vector must be multiple of 4). An error is signaled when the given parameters doesn’t satisfy alignment constraint.


Next: , Previous: , Up: Uniform vectors   [Contents][Index]

9.35.3 Uvector numeric operations

Function: TAGvector-add vec val :optional clamp
Function: TAGvector-add! vec val :optional clamp
Function: TAGvector-sub vec val :optional clamp
Function: TAGvector-sub! vec val :optional clamp
Function: TAGvector-mul vec val :optional clamp
Function: TAGvector-mul! vec val :optional clamp

{gauche.uvector} Element-wise arithmetic. Vec must be a TAGvector, and val must be either a TAGvector, a vector, or a list of the same length as vec, or a number (an exact integer for integer vectors, and a real number for f32- and f64-vectors).

If val is a TAGvector, its elements are added to, subtracted from, or multiplied by the corresponding elements of vec, respectively, and the results are gathered to a TAGvector and returned. The destructive version (those have bang ‘!’ in the name) reuses vec to store the result. If the result of calculation goes out of the range of TAGvector’s element, the behavior is specified by clamp optional argument. (For f32vector and f64vector, clamp argument is ignored and the result may contain infinity).

If val is a number, it is added to, subtracted from, or multiplied by each element of vec, respectively.

(s8vector-add '#s8(1 2 3 4) '#s8(5 6 7 8)) ⇒ #s8(6 8 10 12)
(u8vector-sub '#u8(1 2 3 4) '#u8(2 2 2 2)) ⇒ error
(u8vector-sub '#u8(1 2 3 4) '#u8(2 2 2 2) 'both) ⇒ #u8(0 0 1 2)

(f32vector-mul '#f32(3.0 2.0 1.0) 1.5) ⇒ #f32(4.5 3.0 1.5)
Function: TAGvector-div vec val
Function: TAGvector-div! vec val

{gauche.uvector} Element-wise division of flonum vectors. These are only defined for f16, f32 and f64vector. val must be a TAGvector, a vector or a list of the same length as vec, or a real number.

(f32vector-div '#f32(1.0 2.0 3.0) 2.0) ⇒ #f32(0.5 1.0 1.5)
Function: TAGvector-and vec val
Function: TAGvector-and! vec val
Function: TAGvector-ior vec val
Function: TAGvector-ior! vec val
Function: TAGvector-xor vec val
Function: TAGvector-xor! vec val

{gauche.uvector} Element-wise logical (bitwise) operation. These procedures are only defined for integral vectors. val must be a TAGvector, a vector or a list of the same length as vec, or an exact integer. Bitwise and, inclusive or or exclusive or is calculated between each element in vec and the corresponding element of val (when val is a non-scalar value), or val itself (when val is an integer). The result is returned in a TAGvector. The destructive version reuses vec to store the result.

Function: TAGvector-dot vec0 vec1

{gauche.uvector} Calculates the dot product of two TAGvectors. The length of vec0 and vec1 must be the same.

Function: TAGvector-range-check vec min max

{gauche.uvector} Vec must be a TAGvector, and each of min and max must be either a TAGvector, a vector or a list of the same length as vec, or a number, or #f.

For each element in vec, this procedure checks if the value is between minval and maxval inclusive, where minval and maxval are the corresponding values of min and max (when min and/or max is/are non-scalar value) or min and max themselves (when min and/or max is/are a number). When min is #f, negative infinity is assumed. When max is #f, positive infinity is assumed.

If all the elements in vec are within the range, #f is returned. Otherwise, the index of the leftmost element of vec that is out of range is returned.

(u8vector-range-check '#u8(3 1 0 2) 0 3)  ⇒ #f
(u8vector-range-check '#u8(3 1 0 2) 1 3)  ⇒ 2

(u8vector-range-check '#u8(4 32 64 98) 0 '#u8(10 40 70 90))
  ⇒ 3

;; Range check in a program
(cond
 ((u8vector-range-check u8v 1 31)
  => (lambda (i)
      (errorf "~sth vector element is out of range: ~s"
              i (u8vector-ref u8v i))))
 (else (do-something u8v)))
Function: TAGvector-clamp vec min max
Function: TAGvector-clamp! vec min max

{gauche.uvector} Vec must be a TAGvector, and each of min and max must be either a TAGvector, a vector or a list of the same length as vec, or a number, or #f.

Like TAGvector-range-check, these procedures check if each element of vec are within the range between minval and maxval inclusive, which are derived from min and max. If the value is less than minval, it is replaced by minval. If the value is grater than maxval, it is replaced by maxval.

TAGvector-clamp creates a copy of vec and do clamp operation on it, while TAGvector-clamp! modifies vec. Both return the clamped vector.

(s8vector-clamp '#s8(8 14 -3 -22 0) -10 10) ⇒ #s8(8 10 -3 -10 0)

Previous: , Up: Uniform vectors   [Contents][Index]

9.35.4 Uvector block I/O

A uniform vector can be seen as an abstraction of a chunk of memory. So you might want to use it for binary I/O. Yes, you can do it.

Function: read-uvector class size :optional iport endian

{gauche.uvector} Reads size elements of uvector of class class from iport, and returns fleshly created uvector. If iport is omitted, the curret input port is used.

For example, you can read input as an octet stream as follows:

(with-input-from-string "abcde"
  (^[] (read-uvector <u8vector> 5)))
 ⇒ #u8(97 98 99 100 101)

If the input port has aleady reached EOF, an EOF object is returned. The returned uvector can be shorter than size if the input reaches EOF before size elements are read.

If the iport is a buffered port with ‘modest’ or ‘none’ buffering mode (see File ports), read-uvector may return before size elements are read, even if iport hasn’t reached EOF. The ports connected to a pipe or a network socket behave so by default.

The data is read as a byte stream, so if you give uniform vectors other than s8vector or u8vector, your result may affected by the endianness. If the optional argument endian is given, the input is interpreted in that endianness. When omitted, the value of the parameter default-endian is used. See Endianness, for more about endian handling.

If the size of the input data is unknown and you need to read everything until EOF, use port->uvector below.

R7RS has read-bytevector; it is the same as passing <u8vector> to read-uvector.

Function: read-uvector! vec :optional iport start end endian

{gauche.uvector} Reads a chunk of data from the given input port iport, and stores it to the uniform vector vec. You can give any uniform vector. If optional start and end arguments are given, they specify the index range in vec that is to be filled, and the rest of the vector remains untouched. Otherwise, entire vector is used. A special value -1 for end indicates the end of vec. If iport is omitted, the current input port is used.

If the input reached EOF before the required region of vec is filled, the rest of the vector is untouched.

If iport is already reached EOF when read-uvector! is called, an EOF object is returned. Otherwise, the procedure returns the number of elements read (not bytes).

If the iport is a buffered port with ‘modest’ or ‘none’ buffering mode (see File ports), read-uvector! may return before all the elements in vec is filled, even if iport hasn’t reached EOF. The ports connected to a pipe or a network socket behave so by default. If you know there will be enough data arriving and want to make sure vec is filled, change the buffering mode of iport to ‘full’.

The data is read as a byte stream, so if you give uniform vectors other than s8vector or u8vector, your result may affected by the endianness. If the optional argument endian is given, the input is interpreted in that endianness. When omitted, the value of the parameter default-endian is used. See Endianness, for more about endian handling.

Function: read-block! vec :optional iport start end endian

{gauche.uvector} An old name of read-uvector!. Supported for the backward compatibility, but new code should use read-uvector!.

Function: port->uvector iport :optional class

{gauche.uvector} Read data from the input port iport until EOF and store them into a uvector of class. If class is omitted, <u8vector> is used.

If you specify a class of uvector whose element is more than an octet, the input data is packed with platform’s native byteorder.

This procedure is parallel to port->string etc. (see Input utility functions).

Function: write-uvector vec :optional oport start end endian

{gauche.uvector} Writes out the content of the uniform vector vec ’as is’ to the output port oport. If oport is omitted, the current output port is used. If optional start and end arguments are given, they specify the index range in vec to be written out. A special value -1 for end indicates the end of vec. This procedure returns an unspecified value.

If you write out a uniform vector except s8vector and u8vector, the care should be taken about the endianness, as in read-uvector. The optional argument endian specifies the output endian. When it is omitted, the value of the parameter default-endian is used (see Endianness).

Function: write-block vec :optional oport start end endian

{gauche.uvector} An old name of write-uvector. Supported for the backward compatibility, but new code should use write-uvector.


Previous: , Up: Uniform vectors   [Contents][Index]