Mesh: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
(dzaima/APL update)
m (→‎APL models: Fix expression that used Mask instead of Mesh)
 
(4 intermediate revisions by 3 users not shown)
Line 2: Line 2:
|<math>\backslash{}a,u,b\backslash</math>
|<math>\backslash{}a,u,b\backslash</math>
|}
|}
In [[Iverson notation]], '''Mesh''' (<math>\backslash{}a,u,b\backslash</math>) is a three-argument operation which merges two equal-[[rank]] arguments according to a [[Boolean]] [[vector]]. The relationship between [[Mask]] and Mesh is similar to that between [[Compress]] and [[Expand]]. A related function also named Mesh is implemented in [[NARS]] and [[NARS2000]] as a case of [[Compose]]: <source lang=apl inline>L(a∘\)R</source> combines <source lang=apl inline>L</source> and <source lang=apl inline>R</source> using an integer (not Boolean) control vector. [[Bob Bernecky]] has suggested the syntax <source lang=apl inline>a(u\)b</source> (requiring [[Expand]] to be an [[operator]]) for <math>\backslash{}a,u,b\backslash</math>.<ref>[[Bob Bernecky|Bernecky, Robert]]. "Mask and Mesh Revisited". [[APL2010]].</ref>
In [[Iverson notation]], '''Mesh''' (<math>\backslash{}a,u,b\backslash</math>) is a three-argument operation which merges two equal-[[rank]] arguments according to a [[Boolean]] [[vector]]. The relationship between [[Mask]] and Mesh is similar to that between [[Compress]] and [[Expand]]. A related function also named Mesh is implemented in [[NARS]] and [[NARS2000]] as a case of [[Bind|Compose]]: <syntaxhighlight lang=apl inline>L(a∘\)R</syntaxhighlight> combines <syntaxhighlight lang=apl inline>L</syntaxhighlight> and <syntaxhighlight lang=apl inline>R</syntaxhighlight> using an integer (not Boolean) control vector. [[Bob Bernecky]] has suggested the syntax <syntaxhighlight lang=apl inline>a(u\)b</syntaxhighlight> (requiring [[Expand]] to be an [[operator]]) for <math>\backslash{}a,u,b\backslash</math>.<ref>[[Bob Bernecky|Bernecky, Robert]]. "Mask and Mesh Revisited". [[APL2010]].</ref>


== In Iverson notation ==
== In Iverson notation ==
Line 22: Line 22:
The following forms of Mesh with [[Matrix|matrices]] are defined. Below, matrices are denoted with capital letters while vectors use lowercase letters.
The following forms of Mesh with [[Matrix|matrices]] are defined. Below, matrices are denoted with capital letters while vectors use lowercase letters.
{|class=wikitable
{|class=wikitable
! Iverson notation !! Description !! Modern APL (<source lang=apl inline>⎕IO←0</source>) || Notes
! Iverson notation !! Description !! Modern APL (<syntaxhighlight lang=apl inline>⎕IO←0</syntaxhighlight>) || Notes
|-
|-
| style=text-align:center | <math>\backslash{}A,u,B\backslash</math> || mesh matrices along rows || <source lang=apl inline>u⊃¨⍤1⊢((~u)\A),¨(u\B)</source>
| style=text-align:center | <math>\backslash{}A,u,B\backslash</math> || mesh matrices along rows || <syntaxhighlight lang=apl inline>u⊃¨⍤1⊢((~u)\A),¨(u\B)</syntaxhighlight>
|-
|-
| style=text-align:center | <math>\backslash{}A,U,B\backslash</math> || mesh differently for each row || <source lang=apl inline>U⊃¨⍤1⊢((~U)\⍤1⊢A),¨(U\⍤1⊢B)</source> || where <math>+/U=\nu(A)+\nu(B)</math> in each component  
| style=text-align:center | <math>\backslash{}A,U,B\backslash</math> || mesh differently for each row || <syntaxhighlight lang=apl inline>U⊃¨⍤1⊢((~U)\⍤1⊢A),¨(U\⍤1⊢B)</syntaxhighlight> || where <math>+/U=\nu(A)+\nu(B)</math> in each component  
|-
|-
| style=text-align:center | <math>\backslash{}a,U,b\backslash</math> || mesh vectors in multiple ways || <source lang=apl inline>U⊃¨⍤1⊢((~U)\⍤1⊢A),¨(U\⍤1⊢B)</source> || like the previous with repeated rows in <math>A</math> and <math>B</math>
| style=text-align:center | <math>\backslash{}a,U,b\backslash</math> || mesh vectors in multiple ways || <syntaxhighlight lang=apl inline>U⊃¨⍤1⊢((~U)\⍤1⊢A),¨(U\⍤1⊢B)</syntaxhighlight> || like the previous with repeated rows in <math>A</math> and <math>B</math>
|-
|-
| style=text-align:center | <math>\backslash\!\backslash{}A,u,B\backslash\!\backslash</math> || mesh matrices along columns || <source lang=apl inline>u⊃¨⍤0 1⊢((~u)⍀A),¨(u⍀B)</source> ||
| style=text-align:center | <math>\backslash\!\backslash{}A,u,B\backslash\!\backslash</math> || mesh matrices along columns || <syntaxhighlight lang=apl inline>u⊃¨⍤0 1⊢((~u)⍀A),¨(u⍀B)</syntaxhighlight> ||
|-
|-
| style=text-align:center | <math>\backslash\!\backslash{}A,U,B\backslash\!\backslash</math> || mesh differently for each column || <source lang=apl inline>⍉U⊃¨⍤1⊢((~U)\⍤1⍉A),¨(U\⍤1⍉B)</source> || where <math>+/\!/U=\mu(A)+\mu(B)</math> in each component
| style=text-align:center | <math>\backslash\!\backslash{}A,U,B\backslash\!\backslash</math> || mesh differently for each column || <syntaxhighlight lang=apl inline>⍉U⊃¨⍤1⊢((~U)\⍤1⍉A),¨(U\⍤1⍉B)</syntaxhighlight> || where <math>+/\!/U=\mu(A)+\mu(B)</math> in each component
|-
|-
| style=text-align:center | <math>\backslash\!\backslash{}a,U,b\backslash\!\backslash</math> || mesh vectors differently in each column || <source lang=apl inline>⍉U⊃¨⍤1⊢((~U)\⍤1⍉a),¨(U\⍤1⍉b)</source> || like the previous with repeated columns in <math>A</math> and <math>B</math>
| style=text-align:center | <math>\backslash\!\backslash{}a,U,b\backslash\!\backslash</math> || mesh vectors differently in each column || <syntaxhighlight lang=apl inline>⍉U⊃¨⍤1⊢((~U)\⍤1⍉a),¨(U\⍤1⍉b)</syntaxhighlight> || like the previous with repeated columns in <math>A</math> and <math>B</math>
|}
|}


=== APL models ===
=== APL models ===


In all APLs, <math>/a,u,b/</math> for vectors <math>a</math>, <math>b</math>, and <math>u</math> can be implemented using the [[ordinal]] idiom consisting of two copies of [[Grade]]:
In all APLs, <math>\backslash{}a,u,b\backslash</math> for vectors <math>a</math>, <math>b</math>, and <math>u</math> can be implemented using the [[ordinal]] idiom consisting of two copies of [[Grade]]:
<source lang=apl>
<syntaxhighlight lang=apl>
(a,b)[⍋⍋u]
(a,b)[⍋⍋u]
(b,a)[⍋⍒u]  ⍝ Reversed order by sorting u the other way
(b,a)[⍋⍒u]  ⍝ Reversed order by sorting u the other way
</source>
</syntaxhighlight>
These solutions were published in 1971 by [[Bob Smith]], who attributes them to Luther Woodrum by way of [[Ken Iverson]].<ref>[[Bob Smith|Smith, Bob]]. "Problem section". [[APL Quote-Quad]] Vol. III No. 2&3, p.61.</ref><ref>[[Roger Hui|Hui, Roger]]. [https://www.jsoftware.com/papers/mesh.htm "An Amuse-Bouche from APL History"].</ref> They also appear in the [[FinnAPL idiom library]]. The idea is that every element of <source lang=apl inline>a</source> and <source lang=apl inline>b</source> should be included in the final result, but they are ordered based on <source lang=apl inline>u</source>, so that elements of <source lang=apl inline>a</source> correspond to 0s and those of <source lang=apl inline>b</source> correspond to 1s. Given such a vector, [[Sort by|sorting]] it according to <source lang=apl inline>u</source>, or equivalently, permuting by the [[Grade]] of <source lang=apl inline>u</source>, would return it to the separated vector <source lang=apl inline>a,b</source>. It follows that applying the inverse [[permutation]] <source lang=apl inline>⍋⍋u</source> of <source lang=apl inline>⍋u</source> transforms <source lang=apl inline>a,b</source> into the meshed vector.
These solutions were published in 1971 by [[Bob Smith]], who attributes them to Luther Woodrum by way of [[Ken Iverson]].<ref>[[Bob Smith|Smith, Bob]]. "Problem section". [[APL Quote-Quad]] Vol. III No. 2&3, p.61.</ref><ref>[[Roger Hui|Hui, Roger]]. [https://www.jsoftware.com/papers/mesh.htm "An Amuse-Bouche from APL History"].</ref> They also appear in the [[FinnAPL idiom library]]. The idea is that every element of <syntaxhighlight lang=apl inline>a</syntaxhighlight> and <syntaxhighlight lang=apl inline>b</syntaxhighlight> should be included in the final result, but they are ordered based on <syntaxhighlight lang=apl inline>u</syntaxhighlight>, so that elements of <syntaxhighlight lang=apl inline>a</syntaxhighlight> correspond to 0s and those of <syntaxhighlight lang=apl inline>b</syntaxhighlight> correspond to 1s. Given such a vector, [[Sort by|sorting]] it according to <syntaxhighlight lang=apl inline>u</syntaxhighlight>, or equivalently, permuting by the [[Grade]] of <syntaxhighlight lang=apl inline>u</syntaxhighlight>, would return it to the separated vector <syntaxhighlight lang=apl inline>a,b</syntaxhighlight>. It follows that applying the inverse [[permutation]] <syntaxhighlight lang=apl inline>⍋⍋u</syntaxhighlight> of <syntaxhighlight lang=apl inline>⍋u</syntaxhighlight> transforms <syntaxhighlight lang=apl inline>a,b</syntaxhighlight> into the meshed vector.


Another, more straightforward strategy uses [[selective assignment]] and [[Expand]]. It creates a temporary vector <source lang=apl inline>t</source>, placing elements of <source lang=apl inline>a</source> in the appropriate positions with [[Expand]], and then inserts elements of <source lang=apl inline>b</source> in the appropriate positions by assigning to the [[Compress]] of <source lang=apl inline>t</source>.
Another, more straightforward strategy uses [[selective assignment]] and [[Expand]]. It creates a temporary vector <syntaxhighlight lang=apl inline>t</syntaxhighlight>, placing elements of <syntaxhighlight lang=apl inline>a</syntaxhighlight> in the appropriate positions with [[Expand]], and then inserts elements of <syntaxhighlight lang=apl inline>b</syntaxhighlight> in the appropriate positions by assigning to the [[Compress]] of <syntaxhighlight lang=apl inline>t</syntaxhighlight>.
<source lang=apl>
<syntaxhighlight lang=apl>
t←(~u)\a ⋄ (u/t)←b ⋄ t
t←(~u)\a ⋄ (u/t)←b ⋄ t
</source>
</syntaxhighlight>
The two steps can be reversed, as long as <source lang=apl inline>a</source> is paired with <source lang=apl inline>~u</source> and <source lang=apl inline>b</source> is paired with <source lang=apl inline>u</source>. [[Structural Under]] allows the assignment to be performed in a functional style, with no temporary variable. For example, [[dzaima/APL]] admits these implementations:
The two steps can be reversed, as long as <syntaxhighlight lang=apl inline>a</syntaxhighlight> is paired with <syntaxhighlight lang=apl inline>~u</syntaxhighlight> and <syntaxhighlight lang=apl inline>b</syntaxhighlight> is paired with <syntaxhighlight lang=apl inline>u</syntaxhighlight>. [[Structural Under]] allows the assignment to be performed in a functional style, with no temporary variable. For example, [[dzaima/APL]] admits these implementations:
<source lang=apl>
<syntaxhighlight lang=apl>
b⍨⍢(u∘⌿) (~u)⍀a
b⍨⍢(u∘⌿) (~u)⍀a
a⍨⍢((~u)∘⌿) b⍨⍢(u∘⌿) a,b
a⍨⍢((~u)∘⌿) b⍨⍢(u∘⌿) a,b
</source>{{Works in|[[dzaima/APL]]}}
</syntaxhighlight>{{Works in|[[dzaima/APL]]}}
Here any vector of the same length could be used in place of <source lang=apl inline>a,b</source>.
Here any vector of the same length could be used in place of <syntaxhighlight lang=apl inline>a,b</syntaxhighlight>.


If [[Mask]] is available, for instance as a [[monadic operator]], then Mesh can be obtained by masking together the [[Expand|expansion]] of each argument:
If [[Mask]] is available, for instance as a [[monadic operator]], then Mesh can be obtained by masking together the [[Expand|expansion]] of each argument:
<source lang=apl>
<syntaxhighlight lang=apl>
((~u)\a) (u mask) u\b
((~u)\a) (u mask) u\b
</source>
</syntaxhighlight>
Depending on available language facilities, this idea can be realized in a few different ways. Here the expressions which use [[indexing]] must have the [[index origin]] set to 0.
Depending on available language facilities, this idea can be realized in a few different ways. Here the expressions which use [[indexing]] must have the [[index origin]] set to 0.
<source lang=apl>
<syntaxhighlight lang=apl>
u⊃¨((~u)\a),¨(u\b)          ⍝ Nested APL
u⊃¨((~u)\a),¨(u\b)          ⍝ Nested APL
u(⌷⍤0 1)((~u)\a)(,⍤0)(u\b)  ⍝ With the Rank operator
u(⌷⍤0 1)((~u)\a)(,⍤0)(u\b)  ⍝ With the Rank operator
((~u)\a) ⊣⍢(u∘/) (u\b)      ⍝ Structural Under
((~u)\a) ⊣⍢(u∘/) (u\b)      ⍝ Structural Under
</source>
</syntaxhighlight>


== External Links ==
== External Links ==
Line 79: Line 79:


<references />
<references />
[[Category:APL primitives]][[Category:Iverson notation]]

Latest revision as of 12:48, 19 November 2024

In Iverson notation, Mesh () is a three-argument operation which merges two equal-rank arguments according to a Boolean vector. The relationship between Mask and Mesh is similar to that between Compress and Expand. A related function also named Mesh is implemented in NARS and NARS2000 as a case of Compose: L(a∘\)R combines L and R using an integer (not Boolean) control vector. Bob Bernecky has suggested the syntax a(u\)b (requiring Expand to be an operator) for .[1]

In Iverson notation

Mesh in Iverson notation combines or interleaves two arguments according to a Boolean control. The result has the same shape as the control array, and contains entries taken from the left argument when the control is 0 and from the right when it is 1.

A Programming Language defines the Mesh for vectors and and Boolean vector , where , and , to be the vector whose compressions by and its negation yield the other arguments: and . Conformability requirements give ; because we have .

Mesh is a generalization of Catenate , since meshing with a suffix vector produces .

Iverson notes the following relationships between Mask, Mesh, Compress, and Expand:

The following forms of Mesh with matrices are defined. Below, matrices are denoted with capital letters while vectors use lowercase letters.

Iverson notation Description Modern APL (⎕IO←0) Notes
mesh matrices along rows u⊃¨⍤1⊢((~u)\A),¨(u\B)
mesh differently for each row U⊃¨⍤1⊢((~U)\⍤1⊢A),¨(U\⍤1⊢B) where in each component
mesh vectors in multiple ways U⊃¨⍤1⊢((~U)\⍤1⊢A),¨(U\⍤1⊢B) like the previous with repeated rows in and
mesh matrices along columns u⊃¨⍤0 1⊢((~u)⍀A),¨(u⍀B)
mesh differently for each column ⍉U⊃¨⍤1⊢((~U)\⍤1⍉A),¨(U\⍤1⍉B) where in each component
mesh vectors differently in each column ⍉U⊃¨⍤1⊢((~U)\⍤1⍉a),¨(U\⍤1⍉b) like the previous with repeated columns in and

APL models

In all APLs, for vectors , , and can be implemented using the ordinal idiom consisting of two copies of Grade:

(a,b)[⍋⍋u]
(b,a)[⍋⍒u]  ⍝ Reversed order by sorting u the other way

These solutions were published in 1971 by Bob Smith, who attributes them to Luther Woodrum by way of Ken Iverson.[2][3] They also appear in the FinnAPL idiom library. The idea is that every element of a and b should be included in the final result, but they are ordered based on u, so that elements of a correspond to 0s and those of b correspond to 1s. Given such a vector, sorting it according to u, or equivalently, permuting by the Grade of u, would return it to the separated vector a,b. It follows that applying the inverse permutation ⍋⍋u of ⍋u transforms a,b into the meshed vector.

Another, more straightforward strategy uses selective assignment and Expand. It creates a temporary vector t, placing elements of a in the appropriate positions with Expand, and then inserts elements of b in the appropriate positions by assigning to the Compress of t.

t←(~u)\a ⋄ (u/t)←b ⋄ t

The two steps can be reversed, as long as a is paired with ~u and b is paired with u. Structural Under allows the assignment to be performed in a functional style, with no temporary variable. For example, dzaima/APL admits these implementations:

b⍨⍢(u∘⌿) (~u)⍀a
a⍨⍢((~u)∘⌿) b⍨⍢(u∘⌿) a,b
Works in: dzaima/APL

Here any vector of the same length could be used in place of a,b.

If Mask is available, for instance as a monadic operator, then Mesh can be obtained by masking together the expansion of each argument:

((~u)\a) (u mask) u\b

Depending on available language facilities, this idea can be realized in a few different ways. Here the expressions which use indexing must have the index origin set to 0.

u⊃¨((~u)\a),¨(u\b)          ⍝ Nested APL
u(⌷⍤0 1)((~u)\a)(,⍤0)(u\b)  ⍝ With the Rank operator
((~u)\a) ⊣⍢(u∘/) (u\b)      ⍝ Structural Under

External Links

Documentation

References

  1. Bernecky, Robert. "Mask and Mesh Revisited". APL2010.
  2. Smith, Bob. "Problem section". APL Quote-Quad Vol. III No. 2&3, p.61.
  3. Hui, Roger. "An Amuse-Bouche from APL History".