Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions lib/array.bpl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ disp ← { α←⍬ ⍝ Boxed sketch of nested array.
join←{ ⍝ Join of gap-separated sub-planes.
sep←≢ω ÷ 1ₓ⌈≢α ⍝ sub plane separation.
split←0ₓ=sep|ι≢ω ⊂₀ ω
⊂⍤¯1α plane¨ split ⍝ sub-plane join.
⊂⁻¹α plane¨ split ⍝ sub-plane join.
}
outer←{ ⍝ Outer decoration.
sizes←1 0{↑↓ ⍉⍣α ω}¨seprρ¨ω
Expand Down Expand Up @@ -320,12 +320,12 @@ match ← { ⍝ Wildcard match.
↑{
[[lh lm] [und rm]]←[α ω] ⍝ left and right hits and masks.
[lh∧rm lm] ⍝ right-masked left hits.
}/↓⍉⊃⊂⍤¯1¨[h m]
}/↓⍉⊃⊂⁻¹¨[h m]
}

⍝ From http://dfns.dyalog.com/s_match.htm

showmatch ← {marks←[(α match ω)]⌷" ¯" ◇ ,⍠ ιρρω ω {[α◇ω]}⍤1 marks}
showmatch ← {marks←[(α match ω)]⌷" ¯" ◇ ,⍠ ιρρω ω {[α◇ω]}¹ marks}

⍝ From http://dfns.dyalog.com/n_nlines.htm

Expand Down Expand Up @@ -398,7 +398,7 @@ dscan ← { ⍝ Divide scan
ascan ← { ⍝ Associative scan.
2ₓ>0ₓ⊥ρω?ω; ⍝ few items: done.
lane←⍶{⌽⍶{[(↑ω)⍶α],ω}/⌽[⊂↑ω],1↓ω} ⍝ one lane: builds the results newest first, then reverses them.
lane⍤1 ω
lane¹ ω
}

⍝ From http://dfns.dyalog.com/c_ascana.htm
Expand Down Expand Up @@ -433,7 +433,7 @@ subs ← { ⍝ Vector substitution.
fm⍷ω { ⍝ hits mask
~$t∊α?ω; ⍝ early out if no match
ts↓,/{to,fs↓ω}¨(lead,α)⊂fm,ω
}⍤1 ω ⍝ apply to vectors
}¹ ω ⍝ apply to vectors
}

⍝ From http://dfns.dyalog.com/c_lcase.htm and http://dfns.dyalog.com/c_ucase.htm
Expand Down
14 changes: 7 additions & 7 deletions lib/dyalog.bpl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ lsys←{ ⍝ Lindenmayer L-system expansion.
⍝ From https://dfns.dyalog.com/c_rr.htm
rr←{ ⍝ Round-robin tournament.
v←ιn←0ₓ⌈≤ω
≥(ω÷2)↑₋₁m{[α◇ω]}⍤1⌽m←0ₓ,v⌽≥[n n]ρv
≥(ω÷2)↑₋₁m{[α◇ω]}¹⌽m←0ₓ,v⌽≥[n n]ρv
}

⍝ From https://dfns.dyalog.com/c_easter.htm
Expand Down Expand Up @@ -112,7 +112,7 @@ date←{ ⍝ Timestamp from day number (Meeus).
⍝ From https://dfns.dyalog.com/c_days.htm
days←{ ⍝ Days since 1899-12-31 (Meeus).
α←17520902ₓ
1ₓ<≢ρω?α ∇⍤0 1 ω;
1ₓ<≢ρω?α ∇⁰ ¹ ω;
[yy mm dd h m s ms]←7↑ω
D←dd + [0 60 60 1000]ₓ⊥[h m s ms] ÷ 86400000ₓ
[Y M]←[yy mm]+[¯1 12]ₓ×mm≤2ₓ
Expand Down Expand Up @@ -465,7 +465,7 @@ refmt←{ ⍝ Indent code and align comments.
rlb←{∨\' '≠ω # ω}
clean←⌽ rlb ⌽ rlb code
[clean coms]
}⍤1 ⊃ω
}¹ ⊃ω
dents←{
toks←unqtω {α#⁻α#ω} ω
dvec←-⌿0 1⌽+\"{}"=⊗toks
Expand Down Expand Up @@ -577,7 +577,7 @@ queens←{ ⍝ N-queens solutions up to rotation and reflection.
fmt←{
chars←[(⊃ω)=⊗ια]⌷"·⊛"
expd←1↓,⊃αρ⊂0 1
⊂⍤2 expd#⁻₋₁chars
⊂² expd#⁻₋₁chars
}
squares←[ι⌈ω÷2],1↓ωρ⊂ιω
ω fmt ⍬ search squares
Expand Down Expand Up @@ -670,7 +670,7 @@ von←{ ⍝ Capitalise names, preserving prefixes and user-supplied exceptions.
q←¯1•c{2ₓ>≡ω?,⊂,ω;ω}α
1↓∊∨/q⍶¨⊂' ',ω
}
b←¯1↓∊∨/q⍷¨⊂' ',tx < $t,>/⌽⍤1↕~tx∊" -:;.,!?'""/)("
b←¯1↓∊∨/q⍷¨⊂' ',tx < $t,>/⌽¹↕~tx∊" -:;.,!?'""/)("
b∨←pre(∆pre ∆fix)tx
b>←not(∆not ∆fix)tx
¯1↓(1↣•c)@(⍸b) tx
Expand Down Expand Up @@ -1181,7 +1181,7 @@ tc←{ ⍝ Trace function application.
}

reshape←{ ⍝ α-col reshape of ω.
α=0ₓ?max↑⍤1 col ω; ⍝ item too wide: truncated single col.
α=0ₓ?max↑¹ col ω; ⍝ item too wide: truncated single col.
nr←⌈ni÷ₐα ⍝ number of rows.
matr←[α nr]ρ(α×nr)↑ω,α#' ' ⍝ matrix blank-padded to whole no of cols.
pads←⊃nr#↓gap#' ' ⍝ inter-column padding.
Expand Down Expand Up @@ -1314,7 +1314,7 @@ ratsum←{
[lmrs wids reps]←⍉⊃trans¨[α ω]
mpads←-wids-⊂⌈/wids
rpads←2#⊂∧¨/reps
padded←pad⍤1 ⍉[lmrs◇mpads◇rpads]
padded←pad¹ ⍉[lmrs◇mpads◇rpads]
⊃¨↓⍉padded
}
trans←{
Expand Down
10 changes: 5 additions & 5 deletions lib/numeric.bpl
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ alt ← { ⍝ Alternant.
[r c]←ρω ⍝ matrix ω
0ₓ=r?⍹⌿,ω;
1ₓ≥c?⍶⌿,ω;
M←(ιr)~⍤1⍪ιr ⍝ minors
M←(ιr)~¹⍪ιr ⍝ minors
ω.[: 0]⍶.⍹∇¨⊂₁ ₂[M 1↓ιc]⌷ω
}

Expand Down Expand Up @@ -277,7 +277,7 @@ kcell ← { ⍝ Relationship between point and k-cell.
α←≢ω #₋₁ [2 1]ρ0 1 ⍝ Default is unit k-cell.
b←,⍠(2ₓ=ρρα # 0)α
p←(2⌊ρρα ↓ 1 1,ρω)ρω ⍝ Points to evaluate.
d←,⍶⌿ ⍤1 ⍉×-b,.-p
d←,⍶⌿ ¹ ⍉×-b,.-p
⍶/⍬?⌈/d;5ₓ⊥d
}

Expand Down Expand Up @@ -309,7 +309,7 @@ stdev ← {√(+/÷≢ ω²)-(+/÷≢ ω)²} ⍝ Standard deviation.

NormRand ← { ⍝ Random numbers with a normal distribution
depth←10*9 ⍝ randomness depth
[x y]←⊂⍤¯1 ≥¿depthρ⍨2,ω ÷ depth ⍝ two random variables within ]0;1]
[x y]←⊂⁻¹ ≥¿depthρ⍨2,ω ÷ depth ⍝ two random variables within ]0;1]
(¯2×⊛x * 0.5)×1○π2×y ⍝ Box-Muller distribution
}

Expand Down Expand Up @@ -375,7 +375,7 @@ polar ← { ⍝ Polar from/to cartesian coordinates.
pol_car←{ ⍝ polar from cartesian (default).
radius←{√+⌿ω²} ⍝ radius (pythagorus).
angle←{ ⍝ phase angle.
[x y]←⊂⍤¯1 ω ⍝ x and y coordinates.
[x y]←⊂⁻¹ ω ⍝ x and y coordinates.
[on off]←$t $f=⊂0=x ⍝ points on/off y axis.
atan←3○⁻y÷x+on ⍝ arctan y÷x (avoiding y÷0).
qne←off×atan + on×π0.5×2-×y
Expand All @@ -386,7 +386,7 @@ polar ← { ⍝ Polar from/to cartesian coordinates.
radiusω lam angleω ⍝ (2,···) array of polar coordinates.
}
car_pol←{ ⍝ cartesian from polar.
[r o]←⊂⍤¯1 ω ⍝ radius and phase angle.
[r o]←⊂⁻¹ ω ⍝ radius and phase angle.
r×2○o lam r×1○o ⍝ r×cos(ø), r×sin(ø).
}
lam←{⊃[α ω]}
Expand Down
2 changes: 1 addition & 1 deletion lib/string.bpl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ss ← { ⍝ Approx alternative to xutils' ss.

ssmat ← { ⍝ Matrix search/replace.
[cmat find repl]←ω ⍝ Char matrix, find & replace vectors.
{ss[ω find repl]}⍤1 cmat
{ss[ω find repl]}¹ cmat
}

⍝ From http://dfns.dyalog.com/c_squeeze.htm
Expand Down
6 changes: 3 additions & 3 deletions nbs/arrays.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@
"id": "ccb11a91",
"metadata": {},
"source": [
"When results of different lengths are assembled into one array, the shorter ones are padded with fill. `≥ι ⍤0` gives one row per count:"
"When results of different lengths are assembled into one array, the shorter ones are padded with fill. `≥ι ⁰` gives one row per count:"
]
},
{
Expand All @@ -712,7 +712,7 @@
}
],
"source": [
"≥ι ⍤0 [2 4]"
"≥ι ⁰ [2 4]"
]
},
{
Expand Down Expand Up @@ -1055,7 +1055,7 @@
"id": "733270dc",
"metadata": {},
"source": [
"The results take the array's shape and keys as their frame, as [Rank](glyphs/jot-diaeresis.qmd)'s results do. A keyed array of aggregations gives a keyed result, and through Rank it gives one row of results for each row of its argument:"
"The results take the array's shape and keys as their frame, as [Rank](glyphs/jot-diaeresis.qmd)'s results do. A keyed array of aggregations gives a keyed result, and through Rank it gives one row of results for each row of its argument. The full Rank spelling distinguishes this from `stats¹`, which would raise the array's items to a power:"
]
},
{
Expand Down
10 changes: 5 additions & 5 deletions nbs/autodiff.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ t←1 0 ◇ {f x+ω×t}∂0 ⍝ 3 1
u←1 0 ◇ {+/u×fω}∂ x ⍝ 3 2
```

For a function that works item by item, such as the sine `1○`, `f∂⍤0` gives the derivative at each item. Differentiating along one number gives the same values in one pass:
For a function that works item by item, such as the sine `1○`, `f∂⁰` gives the derivative at each item. Differentiating along one number gives the same values in one pass:

```bpl
x←0 0.5 1
1○∂⍤0 x ⍝ 1 0.8775825619 0.5403023059
1○∂⁰ x ⍝ 1 0.8775825619 0.5403023059
{1○x+ω}∂0 ⍝ 1 0.8775825619 0.5403023059
```

Expand Down Expand Up @@ -125,14 +125,14 @@ Without a program, `∂` builds its duals or its record afresh on every call, th

```bpl
x←ι64 ÷ 63 ◇ y←1○3×x
loss←{[x y]←α ◇ [w b v c]←ω ◇ h←7○b(+⍤1)x×⊗w ◇ +/÷≢ ⊼y-c+h+.×v}
loss←{[x y]←α ◇ [w b v c]←ω ◇ h←7○b(+¹)x×⊗w ◇ +/÷≢ ⊼y-c+h+.×v}
p←["w":1○ι16 "b":16ρ0 "v":0.1×2○ι16 "c":0]
[x y] loss p ⍝ 0.5232276475
p←{ω - 0.1× [x y]loss∂ω}⍣200p
[x y] loss p ⍝ 0.07655752909
```

`∂` runs from a program. The first call with given argument types and shapes traces the function. The function runs on traced values, which have a type and a shape but no items. Each call on a traced value works out the type and shape of its result, and adds a step to the program. A map in the function, such as Rank in `+/{⊼1○+/w×ω}⍤1 X`, calls its dfn once on all its cells, as it does outside a trace. Each call in the dfn then adds one step for all the cells. The derivative's records and transposes add their steps to the same program. The program holds the whole call: the function's value and its derivative together. JAX traces a Python function into a jaxpr in the same way.
`∂` runs from a program. The first call with given argument types and shapes traces the function. The function runs on traced values, which have a type and a shape but no items. Each call on a traced value works out the type and shape of its result, and adds a step to the program. A map in the function, such as Rank in `+/{⊼1○+/w×ω}¹ X`, calls its dfn once on all its cells, as it does outside a trace. Each call in the dfn then adds one step for all the cells. The derivative's records and transposes add their steps to the same program. The program holds the whole call: the function's value and its derivative together. JAX traces a Python function into a jaxpr in the same way.

Later calls with the same argument types and shapes replay the program on their arguments, without running the function. The replay runs the program's steps as ordinary calls. Chains of elementwise steps then run as one stage, a block of items at a time, as they do outside a program. A stage folds its last step's items as it computes them. Its intermediate results exist only one block at a time. Once a stage is large enough, or runs again, BPL compiles it to machine code with Cranelift, if its steps can compile. The browser build has no compiler. It runs every stage on the interpreter's kernels. `•explain` shows whether a call built a program or replayed one:

Expand Down Expand Up @@ -209,7 +209,7 @@ JAX, Dex and tinygrad are the role models. Futhark, Dex and Julia set the standa
| tinygrad | Lazy arrays: a call on a large array gives a pending array, and a read of its items runs the calls it needs, fused. Derivative code that fuses as other code does. Copies, such as a transpose or a slice, whose transposes are copies, not scatters. A program replayed as `TinyJit` replays its kernels. |
| Futhark | One table of partial derivatives for both modes, which BPL's table was mapped from. The rules for folds by `×`, `⌈` and `⌊`. Accumulation as the transpose of a gather. |
| ForwardDiff | Dual numbers with tags, which keep nested derivatives apart. |
| J | `D.`, which gives a Jacobian, and `d.`, which gives the derivative at each item. `f∂` and `f∂⍤0` do these jobs. |
| J | `D.`, which gives a Jacobian, and `d.`, which gives the derivative at each item. `f∂` and `f∂⁰` do these jobs. |

BPL also differs from all of them. `∂` strips its tags from values that escape it, where JAX raises an error when a leaked tracer is used. One operator picks the mode, where JAX offers `jvp`, `vjp`, `jacfwd` and `jacrev`. A Jacobian takes its keys, axis names and records from the rules of outer products. Futhark differentiates its program before running it and recomputes values in reverse mode. BPL differentiates the calls that `f` makes as it runs. It keeps their linear steps instead of recomputing values.

Expand Down
2 changes: 1 addition & 1 deletion nbs/comparison.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ a +˝∘×⎉1‿∞ b

```bpl
a←2 3ρι6ₓ ◇ b←3 2ρι6ₓ
a +⌿×∘⍤1 ∞ b ⍝ [10 13◇28 40]ₓ
a +⌿× ⍤1 ∞ b ⍝ [10 13◇28 40]ₓ
```

### A vector bound into a composition
Expand Down
27 changes: 14 additions & 13 deletions nbs/composition.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ v←2 4 9 ◇ +/÷≢v ⍝ 0ₓ

## Operators on trains

Before an operator, `∘` finishes the current run as that operator's left operand. `⊂⊢∘⌸` is `(⊂⊢)⌸`, and `+/÷≢∘⍤1` is `(+/÷≢)⍤1`. The right operand of a dyadic operator follows as usual:
A run that starts with an operator takes the whole preceding run as its left operand. A space can therefore replace parentheses around a short train: `⊂⊢ ⌸` is `(⊂⊢)⌸`, and `+/÷≢ ¹` is `(+/÷≢)¹`.

```bpl
m←2 3ρι6 ◇ +/÷≢∘⍤1m ⍝ 1 4
m←2 3ρι6 ◇ +/÷≢ ¹m ⍝ 1 4
0 1 0 ⊂⊢ ⌸ "abc" ⍝ "ac" "b"
```

The boundary includes the whole run on its left. Keep a left argument or an earlier function outside that run with spaces or parentheses. Named operators work the same way as glyphs. Before a function, `∘` remains [Atop](#atop-and-over).
The preceding run is the whole operand, including any prefix. Keep a left argument or an earlier function outside it with spaces or parentheses. With both arguments, separate the operand, operator and right argument as above; `0 1 0 ⊂⊢ ⌸"abc"` instead evaluates the rightmost run first. Named operators work the same way as glyphs. Keep parentheses where they show nested structure more clearly.

## Identity functions

Expand Down Expand Up @@ -78,10 +79,10 @@ The two-function train `⌊÷` divides, then rounds down:
-↢10⁝3 ⍝ ¯7
```

With two function operands, `↣` and `↢` form monadic hooks. `f↣g Y` is `(f Y)g Y` and `f↢g Y` is `Y f(g Y)`. Two-function trains in BPL are atops. `(3<)↣# Y` is `(3<Y)#Y`. It keeps the items of `Y` that are greater than 3:
With two function operands, `↣` and `↢` form monadic hooks. `f↣g Y` is `(f Y)g Y` and `f↢g Y` is `Y f(g Y)`. Two-function trains in BPL are atops. `3< ↣# Y` is `(3<Y)#Y`. It keeps the items of `Y` that are greater than 3:

```bpl
(3<)↣# 2 7 1 8 ⍝ 7 8
3< ↣# 2 7 1 8 ⍝ 7 8
```

## Self and Commute
Expand Down Expand Up @@ -110,17 +111,17 @@ fahrenheit←32+1.8× ◇ fahrenheit⁻ 212 ⍝ 100
A superscript straight after a number applies to the number. To invert a function that ends in a number, finish the function before `⁻`:

```bpl
+↢3∘⁻10 ⍝ 7
+↢3 ⁻ 10 ⍝ 7
```

`(+↢3)⁻10` and `+↢3 ⁻ 10` also give `7`. Without a boundary, `+↢3⁻` tries to invert the number `3`, which is a `DOMAIN` error. The signed superscript `3⁻¹` still means one third; `f⁻¹` on a function now means rank ¯1.
`(+↢3)⁻10` also gives `7`. Without grouping, `+↢3⁻` tries to invert the number `3`, which is a `DOMAIN` error. The signed superscript `3⁻¹` still means one third; `f⁻¹` on a function now means rank ¯1.

## Under

[Under](glyphs/at.qmd), `f@g`, applies `f` to what `g` selects and writes the result back. `10×∘@[1 3]` multiplies items 1 and 3 by 10. `⌊@(10×)` rounds down to tenths: it scales by 10, rounds down, then scales back.
[Under](glyphs/at.qmd), `f@g`, applies `f` to what `g` selects and writes the result back. `10× @[1 3]` multiplies items 1 and 3 by 10. `⌊@(10×)` rounds down to tenths: it scales by 10, rounds down, then scales back.

```bpl
10×∘@[1 3] 1 2 3 4 ⍝ 1 20 3 40
10× @[1 3] 1 2 3 4 ⍝ 1 20 3 40
⌊@(10×)1.25 2.78 ⍝ 1.2 2.7
```

Expand All @@ -134,8 +135,8 @@ Within a run, an operator's right operand is the one [token](terms.qmd#term-toke
≥⍣3⁝5 ⍝ 8
m←["r":2 "c":3]ρι6ₓ ◇ i←"c" ◇ +/⍠i⁝m ⍝ ["r":2]ρ[3 12]ₓ
m←["r":2 "c":3]ρι6ₓ ◇ i←"c" ◇ 10÷√1++/⍠i⁝m ⍝ ["r":2]ρ[5 2.773500981]
2×∘⍣3⁝5 ⍝ 40
+/÷≢∘⍤1⁝2 3ρι6 ⍝ 1 4
2× ⍣3⁝5 ⍝ 40
+/÷≢ ⍤1⁝2 3ρι6 ⍝ 1 4
```

Add no separator where the tokens already stay distinct. A name never joins a literal strand, as in `f⍣n1`. A vector argument can touch its operand in brackets, as in `≥⍣2[1 2 3]`.
Expand All @@ -145,7 +146,7 @@ Add no separator where the tokens already stay distinct. A name never joins a li
```bpl
w←[1 2◇3 4◇5 6] ◇ 10 20+⍤1⁝w ⍝ [11 22◇13 24◇15 26]
w←[1 2◇3 4◇5 6] ◇ 10 20(+⍤1)w ⍝ [11 22◇13 24◇15 26]
m←2 3ρι6 ◇ +/÷≢∘⍤1m ⍝ 1 4
m←2 3ρι6 ◇ +/÷≢ ¹m ⍝ 1 4
```

## Forms that read worse
Expand All @@ -157,7 +158,7 @@ Each pair gives the same result with one argument.
| `{(+/ω)÷≢ω}` | `+/÷≢` |
| `0.5×⊢+2÷⊢` | `⊽⁻+÷` |
| `{ω÷+/ω}` | `÷↢ +/` |
| `{ω×10}@[1 3]` | `10×∘@[1 3]` |
| `{ω×10}@[1 3]` | `10× @[1 3]` |
| `{+/ω}⍠0` | `+/₀` |
| `{ω,1}` | `,↢1` |
| `×⍨x` | `x²` |
Expand Down
4 changes: 2 additions & 2 deletions nbs/evaluation.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Operators bind before functions apply. An operator's left [operand](terms.qmd#te

Each run counts as one token, as a parenthesised group does. An operator at the end of a run takes the next run as its right operand, as it takes a touching token: in `⌊@ 10× x`, the right operand of `@` is the run `10×`. An operator at the start of a run takes the previous run as its left operand: in `≢⊢ ⌸x`, the left operand of `⌸` is the run `≢⊢`. Names that hold operators count in both places.

Before an operator, `∘` finishes the whole current run as its left operand: `⊂⊢∘⌸` is `(⊂⊢)⌸`. Spaces keep earlier functions and left arguments outside that run. Before a function, `∘` remains Atop. [Operators on trains](composition.qmd#operators-on-trains) gives examples.
A space can therefore group a short function operand: `⊂⊢ ⌸` is `(⊂⊢)⌸`. With two arguments, `0 1 0 ⊂⊢ ⌸ "abc"` keeps the operand and each argument in its own run. [Operators on trains](composition.qmd#operators-on-trains) gives examples.

```bpl
m←2 3ρι6ₓ ◇ +/⍤1 m ⍝ [3 12]ₓ
Expand Down Expand Up @@ -179,7 +179,7 @@ A guard that reads a cell's value stops batching. The map then calls its operand

A fold or scan by a dfn of an array with more than one lane, such as one along each row of a matrix, makes one batched call for each stage. The call at position `j` runs on item `j` of every lane. `{α-ω}/m` folds every row of `m` from the right with one call for each column, rather than one for each item. In `x f.g y` with a dfn `g`, one batched call runs `g` on every pairing of a row of `x`, a position along the contraction and a column of `y`. `f` then folds along the contraction. Where its batched call stops, a fold or inner product calls its operand once for each item, for the same reasons as a map, below.

`∂` in the operand differentiates with respect to all the cells in one batched call, cells that are arrays included: `{{+/ω*2}∂ω}⍤1 m` gives every row's gradient at once.
`∂` in the operand differentiates with respect to all the cells in one batched call, cells that are arrays included: `{{+/ω*2}∂ω}¹ m` gives every row's gradient at once.

The map calls its operand once for each cell instead where the operand:

Expand Down
2 changes: 1 addition & 1 deletion nbs/gallery/attractor.bpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ frame←{
ω≥1200ₓ?;
new←params map xy
hue←⊢/∧∨⁻⍉new-xy
colour←0.55+0.45×2○hue+⊗0 2.1 4.2 ,⍤1 glow
colour←0.55+0.45×2○hue+⊗0 2.1 4.2 ,¹ glow
xy⊢←new
pos←⍉250+scale×xy-centre
["points":pos,0.8,colour]
Expand Down
Loading