Skip to content

Commit 4f9d117

Browse files
committed
new primal arrays including one-hot vectors
1 parent cbca401 commit 4f9d117

15 files changed

+101
-41
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -837,10 +837,10 @@ April makes available the following APL system variables, constants and function
837837
⎕IO ⎕CT ⎕PP ⎕DIV ⎕RL ⎕A ⎕D ⎕TS ⎕NS ⎕CS ⎕UCS ⎕FMT
838838
```
839839

840-
Additionally, April exposes these system variables and function not found in other APL implementations:
840+
Additionally, April exposes these system variables and functions not found in other APL implementations:
841841

842842
```
843-
⎕OST ⎕DT ⎕XWV ⎕XWF ⎕XWO
843+
⎕OST ⎕TY ⎕XWV ⎕XWF ⎕XWO
844844
```
845845

846846
[Click here to read the names and descriptions of these symbols.](./environmental-symbols.md)
@@ -987,7 +987,7 @@ APL's function editor system and control statements are not implemented; this ty
987987

988988
## April's Lexicon Compared to Other APLs
989989

990-
APL has multiple implementations, and there are subtle but significant variations between the lexical functions they offer. April's set of functions is closest to those offered by Dyalog APL in its default mode. For instance, in April, dyadic `` implements the partitioned enclose function while dyadic `` implements the partition function, as in Dyalog. In IBM APL2, however, there is no partitioned enclose function and dyadic `` implements the partition function. The same is true in GNU APL, whose design primarily follows APL2.
990+
APL has multiple implementations and there are subtle but significant variations between the lexical functions they offer. April's set of functions is closest to those offered by Dyalog APL in its default mode. For instance, in April dyadic `` implements the partitioned enclose function while dyadic `` implements the partition function, as in Dyalog. In IBM APL2, however, there is no partitioned enclose function and dyadic `` implements the partition function. The same is true in GNU APL, whose design primarily follows APL2.
991991

992992
The other major lexical difference between APL2-family languages and April is that in April, monadic `` implements the disclose function and monadic `` implements the mix function; the converse is true in APL2.
993993

demos/fnn/demo.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ To test against only the first N images in the set. In the above case, only the
481481
(let ((net-shape) (net-state) (image-size 0) (training-data) (training-labels) (test-data) (test-labels)
482482
;; tabled vectors representing the target states for the 10 digits
483483
(segment-dims) (tdata-segment) (tsdata-segment) (ovec-length) (output-holder) (oh-segment)
484-
(target-arrays (april "(⊂3⎕DT 10 1↑1)⊖¨⍨-⎕IO-⍨⍳10")))
484+
(target-arrays (april "(⊂3⎕TY 10 1↑1)⊖¨⍨-⎕IO-⍨⍳10")))
485485
(defun load-digit-data ()
486486
"Load the training dataset of handwritten digit images from MNIST."
487487
(unless training-data

environmental-symbols.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ These symbols represent standard functions available within April. Currently, th
5151

5252
|Symbol|Name |Description|
5353
|------|---------------------------|-----------|
54-
|`DT` |Coerce/Get Type |Get enumerated type of an array or coerce an array to an enumerated type.|
54+
|`TY` |Coerce/Get Type |Get enumerated type of an array or coerce an array to an enumerated type.|
5555
|`⎕XWV`|External Workspace Value |Fetch one or more values from another workspace.|
5656
|`⎕XWF`|External Workspace Function|Fetch one or more functions from another workspace.|
5757
|`⎕XWO`|External Workspace Operator|Fetch one or more operators from another workspace.|

functions.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@
301301
(let ((generator (generator-of index)))
302302
(if (not (functionp generator))
303303
generator (funcall generator 0)))))))
304-
(if int-index (make-instance 'vapri-integer-progression :number int-index :origin index-origin)
304+
(if int-index (make-instance 'vapri-arith-provec :number int-index :origin index-origin)
305305
(make-instance 'vapri-coordinate-identity :shape index :index-origin index-origin))))
306306

307307
(defun at-index (index-origin axes)

libraries/dfns/array/array.apl

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ display ← { ⎕IO←0 ⍝ Boxed display of array.
157157
trim{(~1 1=' ')/} removal of extra blank cols
158158
char{:'' ('¯',⎕D)'#~'} simple scalar type
159159
type{{(1=)'+'},char¨} simple array type
160-
line{(49=DT 1)' -'} underline for atom
160+
line{(49=TY 1)' -'} underline for atom
161161

162162
{ ⎕IO0 recursive boxing of arrays:
163163
0=:' '(open ⎕FMT )line simple scalar

spec.lisp

+2-1
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@
261261
(symbols (:variable ⎕ to-output ⎕io *index-origin* ⎕pp print-precision ⎕div *division-method*
262262
⎕ost output-stream ⎕ct *comparison-tolerance* ⎕rl *rngs*)
263263
(:constant ⎕a *alphabet-vector* ⎕d *digit-vector* ⎕ts *apl-timestamp*)
264-
(:function ⎕ns make-namespace ⎕cs change-namespace ⎕dt coerce-or-get-type
264+
(:function ⎕ns make-namespace ⎕cs change-namespace ⎕ty coerce-or-get-type
265265
⎕ucs scalar-code-char ⎕fmt (format-array-uncollated print-precision)
266266
⎕xwv external-workspace-value ⎕xwf external-workspace-function
267267
⎕xwo external-workspace-operator))
@@ -2141,6 +2141,7 @@
21412141
(for "Inverse circular ops." "{(5○⍨-⍵)=⍵∘○⍣¯1⊢5} ⍳12" #(1 1 1 1 1 1 1 1 1 1 1 1))
21422142
(for "Inverse indexing." "⍳⍣¯1⊢1 2 3 4 5" 5)
21432143
(for "Inverse where." "(⍸⍣¯1) 4 5 9" #*000110001)
2144+
(for "Inverse where, right tack-separated." "⍸⍣¯1⊢4 5 9" #*000110001)
21442145
(for "Another inverse where." "(⍸⍣¯1) (1 2) (2 3)" #2A((0 1 0) (0 0 1)))
21452146
(for "Inverse mix." "↑⍣¯2⊢2 3 4⍴⍳9" #(#(#(1 2 3 4) #(5 6 7 8) #(9 1 2 3))
21462147
#(#(4 5 6 7) #(8 9 1 2) #(3 4 5 6))))

utilities.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1374,7 +1374,7 @@
13741374
(error "Not a valid namespace."))))))
13751375

13761376
(defun coerce-or-get-type (array &optional type-index)
1377-
"Create an array with a numerically designated type holding the contents of the given array. Used to implement ⎕DT."
1377+
"Create an array with a numerically designated type holding the contents of the given array. Used to implement ⎕TY."
13781378
(let ((array (vrender array))
13791379
(types '((0 t) (-1 bit) (1 (unsigned-byte 2)) (2 (unsigned-byte 4))
13801380
(-3 (unsigned-byte 7)) (3 (unsigned-byte 8)) (-4 (unsigned-byte 15))

varray/base.lisp

+7-2
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@
717717
(let ((count (aref counts dx)))
718718
(unless (zerop count)
719719
(let ((start-at (aref start-points dx)))
720+
;; (print (list :sa start-points start-at count))
720721
(lambda ()
721722
(funcall jit-gen start-at
722723
count iaddr oaddr)))))))))))
@@ -736,7 +737,7 @@
736737
;; (print (list :st start-at count))
737738
(funcall jit-gen start-at count
738739
(vader-base varray) output)))))))))
739-
740+
;; (when segment-handler (push varray april::*stuff*))
740741
;; (print (list :pro divisions sbesize sbsize))
741742
;; (print (list :out (type-of output) (type-of varray)
742743
;; divisions division-size sbesize sbsize
@@ -745,7 +746,10 @@
745746
;; (vacmp-threadable varray))))
746747
;; (print (list :ts to-nest (setf april::ggt varray)))
747748
;; (print (list :jg jit-gen))
748-
(loop :for d :below divisions :for dx :from 0
749+
;; TODO: segment handler system requires iteration over all threads,
750+
;; is there a way to consolidate the logic?
751+
(loop :for d :below (if segment-handler wcadj divisions)
752+
:for dx :from 0
749753
:do (if (or (and (typep varray 'vader-composing)
750754
(not (vacmp-async varray)))
751755
;; don't thread when rendering the output of operators composed
@@ -973,6 +977,7 @@
973977
(assign-element-type (vader-base varray)))))
974978

975979
(defmethod shape-of :around ((varray varray-derived))
980+
"Extend derived arrays' shape-of methods to collect data on array shape over the course of an array transformation."
976981
(let* ((this-shape (lparallel::force (call-next-method)))
977982
(metadata (metadata-of varray))
978983
(shape-meta (getf metadata :shape)))

varray/calculate.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
(flet ((shape-matches (a)
9797
(loop :for s1 :in shape :for s2 :in (shape-of a) :always (= s1 s2))))
9898
(typecase (vader-base varray)
99-
(vapri-integer-progression nil)
99+
(vapri-arith-provec nil)
100100
((or varray sequence)
101101
(loop :for i :below base-size
102102
:do (let ((a (if base-gen (funcall base-gen i)

varray/composed.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@
293293
:when (and window (= dx axis))
294294
:do (setq wsegment (- dim (1- window))))
295295
(cond
296-
((and scalar-fn (typep (vacmp-omega varray) 'vapri-integer-progression))
296+
((and scalar-fn (typep (vacmp-omega varray) 'vapri-arith-provec))
297297
(get-reduced (vacmp-omega varray) (vacmp-left varray)))
298298
((and (or scalar-fn (and catenate-fn (not window)))
299299
(not out-dims) (arrayp (vacmp-omega varray)))

varray/derived.lisp

+5-3
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,9 @@
364364
(get-promised
365365
(varray-shape varray)
366366
(let ((base (vader-base varray)))
367+
(typecase base (vader-identity (setf base (vader-base base))))
367368
(typecase base
368-
(vapri-integer-progression
369+
(vapri-arith-provec
369370
(if (and (= 1 (vapip-repeat base))
370371
(= 1 (vapip-factor base))
371372
(= (vads-io varray) (vapip-origin base)))
@@ -391,8 +392,9 @@
391392
(defmethod generator-of ((varray vader-inverse-where) &optional indexers params)
392393
(declare (ignore indexers))
393394
(let ((base (vader-base varray)))
395+
(typecase base (vader-identity (setf base (vader-base base))))
394396
(typecase base
395-
(vapri-integer-progression 1)
397+
(vapri-arith-provec 1)
396398
(vapri-coordinate-identity 1)
397399
(vader-where
398400
(setf (vader-content varray)
@@ -3284,7 +3286,7 @@
32843286
(defmethod inverse-count-to ((varray vader-identity) index-origin)
32853287
(inverse-count-to (vader-base varray) index-origin))
32863288

3287-
(defmethod inverse-count-to ((varray vapri-integer-progression) index-origin)
3289+
(defmethod inverse-count-to ((varray vapri-arith-provec) index-origin)
32883290
;; TODO: this does not get invoked by for instance ⍳⍣¯1⊢⍳9 because of the identity varray
32893291
(if (and (= 1 (vapip-repeat varray))
32903292
(= 1 (vapip-factor varray))

varray/effectors-x86-asm.lisp

+15-12
Original file line numberDiff line numberDiff line change
@@ -536,24 +536,26 @@
536536
(etag (case encoding (8 :byte) (16 :word) (32 :dword) (64 :qword))))
537537
(case format
538538
(:x86-asm
539-
(lambda (symbols)
540-
(let ((sum 0))
541-
(loop :for dx :below (rank-of varray)
542-
:do (incf sum (ash (+ (aref (vasec-span varray) dx)
543-
(aref (vasec-pad varray) dx))
544-
(* coordinate-type
545-
(- (rank-of varray) (1+ dx))))))
546-
(destructuring-bind (_ _ _ _ _ _ r8 &rest _) symbols
547-
(declare (ignore _))
548-
(unless (zerop sum)
549-
`((inst add ,etag ,r8 ,sum)))))))
539+
;; current disabled when padding is present
540+
(when (loop :for p :across (vasec-pad varray) :always (zerop p))
541+
(lambda (symbols)
542+
(let ((sum 0))
543+
(loop :for dx :below (rank-of varray)
544+
:do (incf sum (ash (+ (aref (vasec-span varray) dx)
545+
(aref (vasec-pad varray) dx))
546+
(* coordinate-type
547+
(- (rank-of varray) (1+ dx))))))
548+
(destructuring-bind (_ _ _ _ _ _ r8 &rest _) symbols
549+
(declare (ignore _))
550+
(unless (zerop sum)
551+
`((inst add ,etag ,r8 ,sum))))))))
550552
(t (call-next-method)))))
551553

552554
(defmethod effector-of :around ((varray vader-turn) &optional params)
553555
(let* ((format (getf params :format))
554556
(ewidth (getf (rest (getf params :gen-meta)) :index-width))
555557
(cwidth (getf (rest (getf params :gen-meta)) :index-type))
556-
(etag (case ewidth (8 :byte) (16 :word) (32 :dword) (64 :qword)))
558+
(etag (case ewidth (8 :byte) (16 :word) (32 :dword) (64 :qword))) ; 3 4 4 3 3 3 3 3 3 3
557559
(axis (max 0 (if (eq :last (vads-axis varray))
558560
(1- (rank-of varray))
559561
(- (vads-axis varray)
@@ -577,6 +579,7 @@
577579
(let* ((cindex (- (rank-of varray) (1+ axis)))
578580
(adj-degrees (ash (vaturn-degrees varray) (* cwidth cindex)))
579581
(adj-dim (ash dimension (* cwidth cindex)))
582+
;; (ltag (when ))
580583
(mask (ash (1- (expt 2 cwidth)) (* cwidth cindex)))
581584
(ROTATED (gensym)))
582585
(destructuring-bind (ra rc rd rb r6 r7 r8 r9 r10 r11) symbols

varray/logic.lisp

+24-5
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
(make-instance 'vader-enclose :base (funcall function (vader-base (first base))))))))
2323
((= 2 (length base))
2424
(let ((iota-first (and (typep (first base) 'integer)
25-
(typep (second base) 'vapri-integer-progression)))
26-
(iota-second (and (typep (first base) 'vapri-integer-progression)
25+
(typep (second base) 'vapri-arith-provec)))
26+
(iota-second (and (typep (first base) 'vapri-arith-provec)
2727
(typep (second base) 'integer)))
2828
(lex-ref (getf params :lexical-reference)))
2929
(cond ((and lex-ref (or (numberp (first base))
@@ -41,7 +41,7 @@
4141
lex-ref (member lex-ref arith-functions :test #'char=)
4242
(not (and iota-second (char= #\÷ lex-ref))))
4343
(destructuring-bind (iota number) (if iota-second base (reverse base))
44-
(make-instance 'vapri-integer-progression
44+
(make-instance 'vapri-arith-provec
4545
:number (vapip-number iota) :origin (vapip-origin iota)
4646
:offset (if (not (member lex-ref add-sub-functions :test #'char=))
4747
(vapip-offset iota)
@@ -60,6 +60,25 @@
6060
(funcall function number (vapip-factor iota)))))
6161
:repeat (vapip-repeat iota))))))))))))
6262

63+
(defun extend-allocator-vader-inverse-where (&key base argument index-origin)
64+
"Extend allocation behavior of inverse-where class; allows the use of ⍸⍣¯1 to create one-hot vectors."
65+
(declare (ignore argument))
66+
(let ((base-shape (shape-of base)))
67+
(when (and (not (second base-shape))
68+
(first base-shape) (= 1 (first base-shape)))
69+
(let ((base-val (funcall (generator-of base) 0)))
70+
(when (and (integerp base-val) (plusp base-val))
71+
(make-instance 'vapri-onehot-vector :shape (list base-val) :index (- base-val index-origin)))))))
72+
73+
(defun extend-allocator-vader-section (&key base argument inverse axis index-origin)
74+
"Extend allocation behavior of section class; allows resizing of one-hot vectors."
75+
(declare (ignore axis index-origin))
76+
(typecase base
77+
(vapri-onehot-vector (when (or (not (listp argument))
78+
(= 1 (length argument))))
79+
(make-instance 'vapri-onehot-vector :shape (list argument)
80+
:index (vaohv-index base)))))
81+
6382
(defun extend-allocator-vader-permute (&key base argument index-origin)
6483
"Extend allocation behavior of permute class; allows simple inversion of permutation without an argument."
6584
(declare (ignore axis index-origin))
@@ -72,10 +91,10 @@
7291
"Extend allocation behavior of expand class; allows for 3/⍳3 to produce a repeating integer progression vector instead of a vader-expand instance."
7392
(declare (ignore axis index-origin inverse))
7493
(typecase base
75-
(vapri-integer-progression
94+
(vapri-arith-provec
7695
(let ((rendered-argument (unless (shape-of argument) (render argument))))
7796
(when (integerp rendered-argument)
78-
(make-instance 'vapri-integer-progression
97+
(make-instance 'vapri-arith-provec
7998
:number (vapip-number base) :origin (vapip-origin base)
8099
:offset (vapip-offset base) :factor (vapip-factor base)
81100
:repeat (* rendered-argument (vapip-repeat base))))))))

varray/package.lisp

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
(defpackage #:varray
55
(:use #:cl)
66
(:export #:varray #:varrayp #:etype-of #:shape-of #:size-of #:rank-of #:generator-of #:assign-rank
7-
#:vrender #:vapri-integer-progression #:vapri-coordinate-identity #:vader-calculate
7+
#:vrender #:vapri-arith-provec #:vapri-coordinate-identity #:vader-calculate
88
#:vader-select #:vader-random #:vader-deal #:vader-without #:vader-umask
99
#:vader-index #:vader-shape #:vader-reshape #:vader-depth #:vader-first-dim
1010
#:vader-compare #:vader-enlist #:vader-membership #:vader-find #:vader-where

0 commit comments

Comments
 (0)