Array operations

Unary operations

The unary operations are:

Here are a few examples using those operations:

(use-modules (aiscm sequence) (aiscm int) (aiscm jit) (aiscm rgb) (aiscm complex))
(- (seq <int> 2 3 5))
;#<sequence<int<32,signed>>>:
;(-2 -3 -5)
(~ (seq <byte> -128 -3 -2 -1 0 1 2 127))
;#<sequence<int<8,signed>>>:
;(127 2 1 0 -1 -2 -3 -128)
(=0 (seq -2 -1 0 1 2))
;#<sequence<bool>>:
;(#f #f #t #f #f)
(!=0 (seq -2 -1 0 1 2))
;#<sequence<bool>>:
;(#t #t #f #t #t)
(red (seq (rgb 2 3 5) (rgb 3 5 7)))
;#<sequence<int<8,unsigned>>>:
;(2 3)
(green (seq (rgb 2 3 5) (rgb 3 5 7)))
;#<sequence<int<8,unsigned>>>:
;(3 5)
(blue (seq (rgb 2 3 5) (rgb 3 5 7)))
;#<sequence<int<8,unsigned>>>:
;(5 7)
(red (seq 2 3 5))
;#<sequence<int<8,unsigned>>>:
;(2 3 5)
(real-part (seq (complex <sint>) 2+3i 5+7i))
;#<sequence<int<16,signed>>>:
;(2 5)
(real-part (seq 2 3 5))
;#<sequence<int<8,unsigned>>>:
;(2 3 5)
(imag-part (seq (complex <sint>) 2+3i 5+7i))
;#<sequence<int<16,signed>>>:
;(3 7)
(imag-part (seq 2 3 5))
;#<sequence<int<8,unsigned>>>:
;(0 0 0)
(conj (seq (complex <byte>) 2+3i 5+7i))
;#<sequence<complex<int<8,signed>>>:
;(2.0-3.0i 5.0-7.0i)
(conj (seq 2 3 5))
;#<sequence<int<8,unsigned>>>:
;(2 3 5)

Applied to the following image ...

star-ferry.jpg

star-ferry.jpg

... inverting the RGB values yields the following image:

inverted.jpg

inverted.jpg

(use-modules (aiscm magick) (aiscm jit))
(write-image (~ (read-image "star-ferry.jpg")) "inverted.jpg")

Binary operations

The binary operations are:

Furthermore there is rgb for composing RGB values which is a ternary method.

Each binary operation can combine arrays and/or scalars. Most scalar-scalar operations are already part of the Scheme programming language. AIscm mostly needs to provide a few numerical operations and some support for RGB and complex values.

(use-modules (aiscm int) (aiscm rgb) (aiscm complex))
(<< 3 2)
;12
(% 1234 100)
;34
(| 240 15)
;255
(+ (rgb 2 3 5) 1)
;(rgb 3 4 6)
(== (rgb 2 2 2) 2)
;#t

One can use an array-scalar operation to divide each colour channels of an image by a number.

divided.jpg

divided.jpg

(use-modules (aiscm magick) (aiscm rgb) (aiscm sequence) (aiscm jit))
(write-image (/ (read-image "star-ferry.jpg") (rgb 1 1 2)) "divided.jpg")

Another example is using the modulo operator to show the remainder of division by an integer for each channel.

modulo.jpg

modulo.jpg

(use-modules (aiscm magick) (aiscm rgb) (aiscm jit))
(write-image (% (read-image "star-ferry.jpg") (rgb 250 200 150)) "modulo.jpg")

Each binary operation can appear in scalar-array, array-scalar, or array-array form. Also note that the arrays can have different number of dimensions as long as the tail of the shape matches.

(use-modules (aiscm sequence) (aiscm element) (aiscm jit))
(define a (arr (1 2 3) (4 5 6)))
a
;#<sequence<sequence<int<8,unsigned>>>>:
;((1 2 3)
; (4 5 6))
(shape a)
;(3 2)
(define b (seq -1 1))
b
;#<sequence<int<8,signed>>>:
;(-1 1)
(shape b)
;(2)
(+ b 1)
;#<sequence<int<16,signed>>>:
;(0 2)
(+ b b)
;#<sequence<int<8,signed>>>:
;(-2 2)
(- 1 b)
;#<sequence<int<16,signed>>>:
;(2 0)
(* a b)
;#<sequence<sequence<int<16,signed>>>>:
;((-1 -2 -3)
; (4 5 6))

Tensor operations

Tensor notation is a compact way to describe operations involving multi-dimensional arrays. The tensor macro is used to declare a tensor expression. dim and get can be used to create indices and access array elements. sum, prod, largest, and smallest can be used to perform a tensor sum, a cumulative product, or finding the largest/smallest element for a given tensor index. See examples below for the behaviour of tensors.

(use-modules (oop goops) (aiscm sequence) (aiscm tensor) (aiscm expression))
(tensor 42)
;42
(tensor (seq 2 3 5))
;#<sequence<int<8,unsigned>>>:
;(2 3 5)
(tensor (+ (seq 2 3 5) 1))
;#<sequence<int<8,unsigned>>>:
;(3 4 6)
(tensor (dim i (+ (get (seq 2 3 5) i) 1)))
;#<sequence<int<8,unsigned>>>:
;(3 4 6)
(tensor i (+ (get (seq 2 3 5) i) 1))
;#<sequence<int<8,unsigned>>>:
;(3 4 6)
(tensor i j (get (arr (2 3 5) (3 5 7)) j i))
;#<sequence<sequence<int<8,unsigned>>>>:
;((2 3)
; (3 5)
; (5 7))
(tensor i j (+ (get (seq 0 1 2) i) (get (seq 10 20) j)))
;#<sequence<sequence<int<8,unsigned>>>>:
;((10 11 12)
; (20 21 22))
(tensor (prod i (get (seq 2 3 5) i)))
;30
(tensor i (sum j (get (arr (1 2 3) (3 4 5)) i j)))
;#<sequence<int<8,unsigned>>>:
;(4 6 8)
(tensor j (sum i (get (arr (1 2 3) (3 4 5)) i j)))
;#<sequence<int<8,unsigned>>>:
;(6 12)
(tensor i (sum k (* (get (arr (2 3 5) (3 5 7)) k i) (get (seq -1 0 1) k))))
;#<sequence<int<16,unsigned>>>:
;(3 4)
(tensor (largest i (get (arr (2 3 5) (8 6 4)) i)))
;#<sequence<int<8,unsigned>>>:
;(8 6 5)
(tensor (smallest i (get (arr (2 3 5) (8 6 4)) i)))
;#<sequence<int<8,unsigned>>>:
;(2 3 4)

Generated by Pandoc - 2017-12-26