Reshape: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
Miraheze>Adám Brudzewsky
m (Text replacement - "http://help.dyalog.com/latest/Content/Language/" to "http://help.dyalog.com/latest/index.htm#Language/")
m (Text replacement - "<source" to "<syntaxhighlight")
 
(9 intermediate revisions by 5 users not shown)
Line 4: Line 4:


Reshape can be used to produce an array with a given shape and ravel:
Reshape can be used to produce an array with a given shape and ravel:
<source lang=apl>
<syntaxhighlight lang=apl>
       3 4 ⍴ ⍳12
       3 4 ⍴ ⍳12
1  2  3  4
1  2  3  4
5  6  7  8
5  6  7  8
9 10 11 12
9 10 11 12
</source>
</syntaxhighlight>
It appears to exhibit a form of [[Scalar extension|scalar]] or singleton extension:
It appears to exhibit a form of [[Scalar extension|scalar]] or singleton extension:
<source lang=apl>
<syntaxhighlight lang=apl>
       3 4 ⍴ 12
       3 4 ⍴ 12
12 12 12 12
12 12 12 12
12 12 12 12
12 12 12 12
12 12 12 12
12 12 12 12
</source>
</syntaxhighlight>


In fact it repeats an argument of any length, singleton or otherwise. This repetition applies with a vector result, or a higher rank.
In fact it repeats an argument of any length, singleton or otherwise. This repetition applies with a vector result, or a higher rank.
<source lang=apl>
<syntaxhighlight lang=apl>
       12 ⍴ 'abcde'
       12 ⍴ 'abcde'
abcdeabcdeab
abcdeabcdeab
Line 26: Line 26:
eabc
eabc
deab
deab
</source>
</syntaxhighlight>


Reshape can also decrease the rank or [[bound]] of an array. One notable example is the use of an empty left argument <source lang=apl inline>[[Zilde|]]</source> to produce a [[scalar]]. The scalar is the first 0-[[cell]] of the right argument. In [[Nested array model|nested]] languages <source lang=apl inline>⍬⍴</source> is like [[First]] except that it does not remove a layer of nesting.
Reshape can also decrease the rank or [[bound]] of an array. One notable example is the use of an empty left argument [[Zilde]] (<syntaxhighlight lang=apl inline>⍬</syntaxhighlight>) to produce a [[scalar]]. The scalar is the first 0-[[cell]] of the right argument. In [[Nested array model|nested]] languages <syntaxhighlight lang=apl inline>⍬⍴</syntaxhighlight> is like [[First]] except that it does not remove a layer of nesting.
<source lang=apl>
<syntaxhighlight lang=apl>
       9 ⍴ ∘.+⍨ 1 2 1
       9 ⍴ ∘.+⍨ 1 2 1
2 3 2 3 4 3 2 3 2
2 3 2 3 4 3 2 3 2
Line 38: Line 38:
│1 1│
│1 1│
└───┘
└───┘
</source>
</syntaxhighlight>


== Description ==
== Description ==
Line 50: Line 50:
== APL model ==
== APL model ==


Since Reshape itself is the fundamental way to create a multi-dimensional array in APL, the function as a whole cannot be modelled in terms of more fundamental primitives. However, we may express it in terms of a stricter reshaping function <source lang=apl inline>shape</source>, which forms an array from its [[shape]] and [[ravel]] vectors, requiring both to have rank 1 and the number of elements in the ravel to be the product of the shape. <source lang=apl inline>shape</source> is identical to Reshape on its domain, but it has a strictly smaller domain than Reshape. The extensions required to implement Reshape are that a scalar left argument must be allowed, and that the right argument must be converted to a vector with the appropriate length, truncating or repeating its elements.
Since Reshape itself is the fundamental way to create a multi-dimensional array in APL, the function as a whole cannot be modelled in terms of more fundamental primitives. However, we may express it in terms of a stricter reshaping function <syntaxhighlight lang=apl inline>shape</syntaxhighlight>, which forms an array from its [[shape]] and [[ravel]] vectors, requiring both to have rank 1 and the number of elements in the ravel to be the product of the shape. <syntaxhighlight lang=apl inline>shape</syntaxhighlight> is identical to Reshape on its domain, but it has a strictly smaller domain than Reshape. The extensions required to implement Reshape are that a scalar left argument must be allowed, and that the right argument must be converted to a vector with the appropriate length, truncating or repeating its elements.
<source lang=apl>
<syntaxhighlight lang=apl>
Reshape ← {
Reshape ← {
     (1/⍺) shape (×/⍺) {(0=≢⍵)∨⍺≤≢⍵:⍺↑⍵ ⋄ ⍺∇,⍨⍵} ,⍵
     (1/⍺) shape (×/⍺) {(0=≢⍵)∨⍺≤≢⍵:⍺↑⍵ ⋄ ⍺∇,⍨⍵} ,⍵
}
}
</source>
</syntaxhighlight>
{{Works in|[[Dyalog APL]],[[ngn/apl]]}}
{{Works in|[[Dyalog APL]],[[ngn/apl]]}}
The above implementation performs truncation and fill element generation using [[Take]], after extending the [[Ravel|ravelled]] right argument by [[Catenate|catenating]] it with itself until it is long enough. An implementation using indices instead of structural manipulation is also possible:
The above implementation performs truncation and fill element generation using [[Take]], after extending the [[Ravel|ravelled]] right argument by [[Catenate|catenating]] it with itself until it is long enough. An implementation using indices instead of structural manipulation is also possible:
<source lang=apl>
<syntaxhighlight lang=apl>
Reshape ← {
Reshape ← {
     ⎕IO←0
     ⎕IO←0
     (1/⍺) shape ((,⍵),(⊂⊃⍵))[(1⌈×/⍴⍵)|⍳×/⍺]
     (1/⍺) shape ((,⍵),(⊂⊃⍵))[(1⌈×/⍴⍵)|⍳×/⍺]
}
}
</source>
</syntaxhighlight>
{{Works in|[[Dyalog APL]]}}
{{Works in|[[Dyalog APL]]}}
Here the right argument is converted to a ravel vector by ravelling and appending the [[prototype]], then [[indexing]] to produce a vector of the correct length. The indices used are the ravel indices of the result, but they are made to wrap around using [[Residue]].
Here the right argument is converted to a ravel vector by ravelling and appending the [[prototype]], then [[Bracket indexing|indexing]] to produce a vector of the correct length. The indices used are the ravel indices of the result, but they are made to wrap around using [[Residue]].


== J variant: Shape ==
== J variant: Shape ==


The [[J]] language does not include a Reshape primitive. In J, the monadic [[Shape]] function is called "Shape Of" and uses the glyph <source lang=apl inline>$</source>. Its dyadic form, simply called "Shape", rearranges the [[Major cell|major cells]] of the right argument rather than its [[elements]]. The result shape is given by the left argument, followed by the shape of the right argument with the first [[axis]] length (if any) removed. In APL the J Shape function can be written <source lang=apl inline>{ (⍺,1↓⍴⍵)⍴⍵ }</source>, and in J the APL Reshape function can be written using the [[hook]] <source lang=apl inline>($,)</source> which first ravels the right argument so that its major cells are its elements.
The [[J]] language does not include a Reshape primitive. In J, the monadic [[Shape]] function is called "Shape Of" and uses the glyph <syntaxhighlight lang=apl inline>$</syntaxhighlight>. Its dyadic form, simply called "Shape", rearranges the [[Major cell|major cells]] of the right argument rather than its [[elements]]. The result shape is given by the left argument, followed by the shape of the right argument with the first [[axis]] length (if any) removed. In APL the J Shape function can be written <syntaxhighlight lang=apl inline>{ (⍺,1↓⍴⍵)⍴⍵ }</syntaxhighlight>, and in J the APL Reshape function can be written using the [[hook]] <syntaxhighlight lang=apl inline>($,)</syntaxhighlight> which first ravels the right argument so that its major cells are its elements.


== Notable uses ==
== Notable uses ==


Reshape can be used to produce an [[identity matrix]] by reshaping a vector which is one longer than the desired side length.
Reshape can be used to produce an [[wikipedia:identity matrix|identity matrix]] by reshaping a vector which is one longer than the desired side length.
<source lang=apl>
<syntaxhighlight lang=apl>
       4 4 ⍴ 5↑1
       4 4 ⍴ 5↑1
1 0 0 0
1 0 0 0
Line 80: Line 80:
0 0 1 0
0 0 1 0
0 0 0 1
0 0 0 1
</source>
</syntaxhighlight>
This idea might be written in a [[tacit]] style as <source lang=apl inline>,⍨⍴1↑⍨1∘+</source> or <source lang=apl inline>,⍨⍴1,⍴∘0</source>. Both functions take the side length as an argument and produce an identity matrix with that side length.
This idea might be written in a [[tacit]] style as <syntaxhighlight lang=apl inline>,⍨⍴1↑⍨1∘+</syntaxhighlight> or <syntaxhighlight lang=apl inline>,⍨⍴1,⍴∘0</syntaxhighlight>. Both functions take the side length as an argument and produce an identity matrix with that side length.


== External links ==
== External links ==
Line 88: Line 88:


* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-10-apl-functions-- APL Cultivation]
* [https://chat.stackexchange.com/rooms/52405/conversation/lesson-10-apl-functions-- APL Cultivation]
* [https://www.sacrideo.us/apl-a-day-4-arrays-have-elements/ Arrays have elements] (part of [https://www.sacrideo.us/tag/apl-a-day/ APL a Day])


=== Documentation ===
=== Documentation ===


* [http://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Reshape.htm Dyalog]
* [https://help.dyalog.com/latest/index.htm#Language/Primitive%20Functions/Reshape.htm Dyalog]
 
* [http://wiki.nars2000.org/index.php/Rho NARS2000]
* [http://wiki.nars2000.org/index.php/Rho NARS2000]
* [http://microapl.com/apl_help/ch_020_020_470.htm APLX]
* [http://microapl.com/apl_help/ch_020_020_470.htm APLX]
* [https://code.jsoftware.com/wiki/Vocabulary/dollar#dyadic J Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/dollar#dyadic J NuVoc] (as <syntaxhighlight lang=apl inline>$</syntaxhighlight> "Shape")
* [https://mlochbaum.github.io/BQN/doc/reshape.html BQN]


* [https://code.jsoftware.com/wiki/Vocabulary/dollar#dyadic J Dictionary], [https://code.jsoftware.com/wiki/Vocabulary/dollar#dyadic J NuVoc] (as <source lang=apl inline>$</source> "Shape")
{{APL built-ins}}[[Category:Primitive functions]]
 
{{APL built-ins}}

Latest revision as of 22:26, 10 September 2022

Reshape () produces an array with shape given by the left argument and elements from the right argument. Elements are copied from the right argument to the result in ravel order, truncating if the result has smaller bound than the right argument and repeating cyclically if it has larger bound. If the right argument is empty, fills are used for the result elements.

Examples

Reshape can be used to produce an array with a given shape and ravel:

      3 4 ⍴ ⍳12
1  2  3  4
5  6  7  8
9 10 11 12

It appears to exhibit a form of scalar or singleton extension:

      3 4 ⍴ 12
12 12 12 12
12 12 12 12
12 12 12 12

In fact it repeats an argument of any length, singleton or otherwise. This repetition applies with a vector result, or a higher rank.

      12 ⍴ 'abcde'
abcdeabcdeab
      3 4 ⍴ 'abcde'
abcd
eabc
deab

Reshape can also decrease the rank or bound of an array. One notable example is the use of an empty left argument Zilde () to produce a scalar. The scalar is the first 0-cell of the right argument. In nested languages ⍬⍴ is like First except that it does not remove a layer of nesting.

      9 ⍴ ∘.+⍨ 1 2 1
2 3 2 3 4 3 2 3 2
      3 ⍴ 'Samantha'
Sam
      ⍬ ⍴ ⍳8 8
┌───┐
│1 1│
└───┘

Description

The left argument of Reshape must be a valid shape, or vector of nonnegative integers, after scalar rank extension (that is, a scalar is treated as a one-element vector). The right argument may be any array. The result array is an array of the given shape, and its elements in ravel order are taken from the right argument in ravel order. If the right argument's ravel is too short, they are repeated starting at the beginning again as many times as necessary.

An empty right argument will cause the result array to be composed of fill elements. Reshape is similar to Take in this case—in fact, Take with an empty right argument is always identical to Reshape unless it results in an error.

The ravelled result is either a prefix of the ravelled argument, or a suffix.

APL model

Since Reshape itself is the fundamental way to create a multi-dimensional array in APL, the function as a whole cannot be modelled in terms of more fundamental primitives. However, we may express it in terms of a stricter reshaping function shape, which forms an array from its shape and ravel vectors, requiring both to have rank 1 and the number of elements in the ravel to be the product of the shape. shape is identical to Reshape on its domain, but it has a strictly smaller domain than Reshape. The extensions required to implement Reshape are that a scalar left argument must be allowed, and that the right argument must be converted to a vector with the appropriate length, truncating or repeating its elements.

Reshape ← {
    (1/⍺) shape (×/⍺) {(0=≢⍵)∨⍺≤≢⍵:⍺↑⍵ ⋄ ⍺∇,⍨⍵} ,⍵
}

The above implementation performs truncation and fill element generation using Take, after extending the ravelled right argument by catenating it with itself until it is long enough. An implementation using indices instead of structural manipulation is also possible:

Reshape ← {
    ⎕IO←0
    (1/⍺) shape ((,⍵),(⊂⊃⍵))[(1⌈×/⍴⍵)|⍳×/⍺]
}
Works in: Dyalog APL

Here the right argument is converted to a ravel vector by ravelling and appending the prototype, then indexing to produce a vector of the correct length. The indices used are the ravel indices of the result, but they are made to wrap around using Residue.

J variant: Shape

The J language does not include a Reshape primitive. In J, the monadic Shape function is called "Shape Of" and uses the glyph $. Its dyadic form, simply called "Shape", rearranges the major cells of the right argument rather than its elements. The result shape is given by the left argument, followed by the shape of the right argument with the first axis length (if any) removed. In APL the J Shape function can be written { (⍺,1↓⍴⍵)⍴⍵ }, and in J the APL Reshape function can be written using the hook ($,) which first ravels the right argument so that its major cells are its elements.

Notable uses

Reshape can be used to produce an identity matrix by reshaping a vector which is one longer than the desired side length.

      4 4 ⍴ 5↑1
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

This idea might be written in a tacit style as ,⍨⍴1↑⍨1∘+ or ,⍨⍴1,⍴∘0. Both functions take the side length as an argument and produce an identity matrix with that side length.

External links

Lessons

Documentation


APL built-ins [edit]
Primitives (Timeline) Functions
Scalar
Monadic ConjugateNegateSignumReciprocalMagnitudeExponentialNatural LogarithmFloorCeilingFactorialNotPi TimesRollTypeImaginarySquare RootRound
Dyadic AddSubtractTimesDivideResiduePowerLogarithmMinimumMaximumBinomialComparison functionsBoolean functions (And, Or, Nand, Nor) ∙ GCDLCMCircularComplexRoot
Non-Scalar
Structural ShapeReshapeTallyDepthRavelEnlistTableCatenateReverseRotateTransposeRazeMixSplitEncloseNestCut (K)PairLinkPartitioned EnclosePartition
Selection FirstPickTakeDropUniqueIdentityStopSelectReplicateExpandSet functions (IntersectionUnionWithout) ∙ Bracket indexingIndexCartesian ProductSort
Selector Index generatorGradeIndex OfInterval IndexIndicesDealPrefix and suffix vectors
Computational MatchNot MatchMembershipFindNub SieveEncodeDecodeMatrix InverseMatrix DivideFormatExecuteMaterialiseRange
Operators Monadic EachCommuteConstantReplicateExpandReduceWindowed ReduceScanOuter ProductKeyI-BeamSpawnFunction axisIdentity (Null, Ident)
Dyadic BindCompositions (Compose, Reverse Compose, Beside, Withe, Atop, Over) ∙ Inner ProductDeterminantPowerAtUnderRankDepthVariantStencilCutDirect definition (operator)Identity (Lev, Dex)
Quad names Index originComparison toleranceMigration levelAtomic vector