Arrays can be instantiated using a type specification. Note that the elements are not guaranteed to be initialised:
(use-modules (oop goops) (aiscm int) (aiscm sequence))
(make (sequence <ubyte>) #:size 100)
;#<sequence<int<8,unsigned>>>:
;(128 24 172 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...)
Uniform arrays can also be created from values using type matching:
It is also possible to instantiate multi-dimensional arrays. Again elements are not guaranteed to be initialised:
(use-modules (oop goops) (aiscm int) (aiscm sequence))
(make (multiarray <int> 2) #:shape '(6 4))
;#<sequence<int<32,signed>>>>:
;((21701840 0 0 0 0 0)
; (0 0 0 0 0 0)
; (0 0 0 0 0 0)
; (0 0 0 0 0 0))
Uniform multi-dimensional arrays can also be created from values using type matching:
(use-modules (aiscm sequence))
(arr ((1 2) (3 4)) ((5 6) (7 8)))
;#<sequence<sequence<sequence<int<8,unsigned>>>>>:
;(((1 2)
; (3 4))
; ((5 6)
; (7 8)))
Scheme list objects can be converted to uniform arrays and vice versa using the methods to-array and to-list:
(use-modules (aiscm sequence) (aiscm int) (aiscm rgb))
(define l (list (list (rgb 1 2 3) (rgb 4 5 6)) (list (rgb 2 3 4) (rgb 5 6 7))))
(define a (to-array l))
a
;#<sequence<sequence<rgb<int<8,unsigned>>>>:
;(((rgb 1 2 3) (rgb 4 5 6))
; ((rgb 2 3 4) (rgb 5 6 7)))
(to-list a)
;(((rgb 1 2 3) (rgb 2 3 4)) ((rgb 4 5 6) (rgb 5 6 7)))
to-array uses type matching to determine the most suitable type.
The dimension is the number of array indices used to select an element. The shape is a list specifying the size of the array in each direction. The stride specifies the internal memory layout of the array.
(use-modules (aiscm sequence) (aiscm int) (aiscm element))
(define a (arr <int> ((1 2 3) (4 5 6))))
(dimensions a)
;3
(size a)
;6
(size-of a)
;24
(shape a)
;(3 2 1)
(strides a)
;(1 3 6)
(get a 1 0 0)
;2
(get a 0 0)
;#<sequence<int<32,signed>>>:
;(1 2 3)
The array size denotes the number of elements while size-of tells the storage size of the array. The get method can be used to extract elements or array slices.
Boolean arrays are used to store true and false values. They can be converted to integer arrays and back if required.
(use-modules (aiscm sequence) (aiscm int) (aiscm bool) (aiscm jit))
(define b (seq #f #f #t #t #f #t))
b
;#<sequence<bool>>:
;(#f #f #t #t #f #t)
(define u (to-type <ubyte> b))
u
;#<sequence<int<8,unsigned>>>:
;(0 0 1 1 0 1)
(to-type <bool> u)
u
;#<sequence<bool>>:
;(#f #f #t #t #f #t)
It is also possible to specify the array type when creating an array from values:
(use-modules (aiscm int) (aiscm sequence))
(seq <int> 2 3 5 7)
;#<sequence<int<32,signed>>>:
;(2 3 5 7)
Note that the integer type can be specified using number of bits and signed-ness instead:
(use-modules (aiscm int) (aiscm sequence))
(seq (integer 32 unsigned) 2 3 5 7)
;#<sequence<int<32,signed>>>:
;(2 3 5 7)
Given the following image …
… rolling the dimensions will result in the following image:
(use-modules (aiscm magick) (aiscm sequence))
(define img (read-image "pavillion.jpg"))
(write-image (roll img) "rolled.jpg")
roll and unroll cycle the dimensions of the array around. Here is and example with a 3D array:
(use-modules (aiscm sequence) (aiscm element))
(define a (arr ((1 2 3) (4 5 6))))
a
;#<sequence<sequence<sequence<sequence<int<8,unsigned>>>>>>:
;((((1 2 3)
; (4 5 6))))
(shape a)
;(3 2 1)
(roll a)
;#<sequence<sequence<sequence<sequence<int<8,unsigned>>>>>>:
;(((1 4))
; ((2 5))
; ((3 6)))
(shape (roll a))
;(2 1 3)
(unroll a)
;#<sequence<sequence<sequence<sequence<int<8,unsigned>>>>>>:
;(((1)
; (2)
; (3))
; ((4)
; (5)
; (6)))
(shape (unroll a))
;(1 3 2)
(project (roll a))
;#<sequence<sequence<int<8,unsigned>>>>:
;((1 4))
The project method can be used to extract the first slice of an array.
One can dump array slices from the beginning of the array and crop the length of the array, i.e. removing slices from the end of the array.
(use-modules (aiscm magick) (aiscm sequence))
(write-image (crop 200 (dump 20 (read-image "pavillion.jpg"))) "cropped.jpg")
The dump and crop command can also take a list of values in order to extract a part of a multi-dimensional array:
(use-modules (aiscm magick) (aiscm sequence))
(write-image (crop '(250 200) (dump '(27 20) (read-image "pavillion.jpg"))) "crop2d.jpg")
The rgb method can be used to combine colour values and images. The following program swaps the colour channels around:
(use-modules (aiscm magick) (aiscm rgb))
(define img (read-image "pavillion.jpg"))
(write-image (rgb (red img) (blue img) (green img)) "swap-channels.jpg")
At the moment only integer complex values are supported. Here is a small example using complex arrays:
(use-modules (aiscm complex) (aiscm sequence) (aiscm int) (aiscm jit))
(define c (seq 2+3i 5+7i))
c
;#<sequence<complex<int<8,unsigned>>>:
;(2.0+3.0i 5.0+7.0i)
(real-part c)
;#<sequence<int<8,unsigned>>>:
;(2 5)
(imag-part c)
;#<sequence<int<8,unsigned>>>:
;(3 7)
(complex (seq 2 5) (seq 3 7))
;#<sequence<complex<int<8,unsigned>>>:
;(2.0+3.0i 5.0+7.0i)
(conj c)
;#<sequence<complex<int<8,unsigned>>>:
;(2.0+253.0i 5.0+249.0i)
(conj (to-type (complex <byte>) c))
;#<sequence<complex<int<8,signed>>>:
;(2.0-3.0i 5.0-7.0i)
Since native integers are used, numerical overflow can occur. Note that you can use to-type to convert an array to a more suitable type.
It is also possible to use arrays of Scheme objects instead of using a native representation:
(use-modules (oop goops) (aiscm sequence) (aiscm obj) (aiscm jit))
(<< 1 (* 10 (seq <obj> 1 2 4 8)))
;#<sequence<obj>>:
;(1024 1048576 1099511627776 1208925819614629174706176)