Arrays

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 core))
(make (multiarray <ubyte> 1) #:shape '(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 core))
(arr -1 2 3 5)
;#<multiarray<int<8,signed>,1>>:
;(-1 2 3 5)

The fill method can be used to create an array where the elements are initialised:

(use-modules (oop goops) (aiscm core) (aiscm xorg))
(show (fill (rgb <ubyte>) '(240 320) (rgb 0 255 0)))

Index arrays can be used to generate x- and y-ramp arrays:

(use-modules (oop goops) (aiscm core))
(define idx (indices 3 2))
idx
;#<multiarray<int<32,signed>,2>>:
;((0 1 2
; (3 4 5)))
(/ idx 3)
;#<multiarray<int<32,signed>,2>>:
;((0 0 0
; (1 1 1)))
(% idx 3)
;#<multiarray<int<32,signed>,2>>:
;((0 1 2
; (0 1 2)))

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 core))
(make (multiarray <int> 2) #:shape '(6 4))
;#<multiarray<int<32,signed>,2>>:
;((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 core))
(arr ((1 2) (3 4)) ((5 6) (7 8)))
;#<multiarray<int<8,unsigned>,3>>:
;(((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 core))
(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
;#<multiarray<rgb<int<8,unsigned>>,2>>:
;(((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 core))
(define a (arr <int> ((1 2 3) (4 5 6))))
(dimensions a)
;3
(size-of a)
;24
(shape a)
;(1 2 3)
(strides a)
;(24 12 4)
(get a 1 0 0)
;2
(get a 0 0)
;#<multiarray<int<32,signed>,1>>:
;(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 core))
(define b (arr #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 core))
(arr <int> 2 3 5 7)
;#<multiarray<int<8,unsigned>,1>>:
;(2 3 5 7)

Note that the integer type can be specified using number of bits and signed-ness instead:

(use-modules (aiscm core))
(arr <int> 2 3 5 7)
;#<multiarray<int<32,signed>>,1>:
;(2 3 5 7)

Rolling dimensions

Given the following image …

pavillion.jpg

… rolling the dimensions will result in the following image:

rolled.jph
(use-modules (aiscm magick) (aiscm core))
(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 core))
(define a (arr ((1 2 3) (4 5 6))))
a
;#<multiarray<int<8,unsigned>,3>>:
;((((1 2 3)
;   (4 5 6))))
(shape a)
;(1 2 3)
(unroll a)
;#<multiarray<int<8,unsigned>,3>>:
;(((1 4))
; ((2 5))
; ((3 6)))
(shape (unroll a))
;(3 1 2)
(roll a)
;#<multiarray<int<8,unsigned>,3>>:
;(((1)
;  (2)
;  (3))
; ((4)
;  (5)
;  (6)))
(shape (roll a))
;(2 3 1)
(get (unroll a) 0)
;#<multiarray<int<8,unsigned>,2>>:
;((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
(use-modules (aiscm magick) (aiscm core))
(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
(use-modules (aiscm magick) (aiscm core))
(write-image (crop '(200 250) (dump '(20 27) (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
(use-modules (aiscm magick) (aiscm core))
(define img (read-image "pavillion.jpg"))
(write-image (rgb (red img) (blue img) (green img)) "swap-channels.jpg")

One can convert a stereoscopic image into a red-cyan anaglyph image for 3D viewing as shown below.

shuttle.jpg
(use-modules (oop goops) (aiscm magick) (aiscm xorg) (aiscm core))
(define image (read-image "shuttle.jpg"))
(define width (cadr (shape image)))
(define height (car (shape image)))
(define left (crop (list height (/ width 2)) image))
(define right (dump (list 0 (/ width 2)) image))
(show (rgb (red left) (/ (green right) 2) (/ (blue right) 2)))

Complex values

Here is a small example using complex arrays:

(use-modules (aiscm core))
(define c (arr 2+3i 5+7i))
c
;#<multiarray<complex<float<double>>,1>>:
;(2.0+3.0i 5.0+7.0i)
(real-part c)
;#<multiarray<float<double>,1>>:
;(2.0 5.0)
(imag-part c)
;#<multiarray<float<double>,1>>:
;(3.0 7.0)
(complex (arr 2 5) (arr 3 7))
;#<multiarray<complex<float<double>>,1>>:
;(2.0+3.0i 5.0+7.0i)
(conj c)
;#<multiarray<complex<float<double>>,1>>:
;(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.


AIscm documentation generated by Pandoc 2023-02-14