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
... inverting the RGB values yields the following image:
inverted.jpg
(use-modules (aiscm magick) (aiscm jit))
(write-image (~ (read-image "star-ferry.jpg")) "inverted.jpg")
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
(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
(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 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. inject can be used to perform tensor summation or other cummulative operations. 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)