Array manipulation

Array construction

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:

(use-modules (aiscm sequence))
(seq -1 2 3 5)
;#<sequence<int<8,signed>>>:
;(-1 2 3 5)

Multi-dimensional arrays

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)))

Conversion from/to lists

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.

Dimension, shape, and strides

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

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)

Integer types

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)

Rolling dimensions

Given the following image ...

pavillion.jpg

pavillion.jpg

... rolling the dimensions will result in the following image:

rolled.jph

rolled.jph

(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.

Cropping arrays and dumping elements

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.

cropped.jpg

cropped.jpg

(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:

crop2d.jpg

crop2d.jpg

(use-modules (aiscm magick) (aiscm sequence))
(write-image (crop '(250 200) (dump '(27 20) (read-image "pavillion.jpg"))) "crop2d.jpg")

RGB values

The rgb method can be used to combine colour values and images. The following program swaps the colour channels around:

swap-channels.jpg

swap-channels.jpg

(use-modules (aiscm magick) (aiscm rgb))
(define img (read-image "pavillion.jpg"))
(write-image (rgb (red img) (blue img) (green img)) "swap-channels.jpg")

Complex values

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.

Object arrays

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)

Generated by Pandoc - 2017-03-30