Reduce: Difference between revisions

From APL Wiki
Jump to navigation Jump to search
Tags: Mobile edit Mobile web edit
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Built-ins|Reduce|/|⌿}}, also called '''Reduction''' or '''Insert''', is a [[primitive operator|primitive]] [[monadic operator]] which takes a [[dyadic function]] [[operand]], inserts it between the [[element|elements]] of the [[argument]], and evaluates it into a single array in right-to-left order. This operation is known as [[wikipedia:Fold (higher-order function)|Fold]], or more specifically <source lang=text inline>foldr1</source>, in other functional programming languages such as Haskell.
{{Built-ins|Reduce|/|⌿}}, also called '''Reduction''' or '''Insert''', is a [[primitive operator|primitive]] [[monadic operator]] which takes a [[dyadic function]] [[operand]], inserts it between the [[element|elements]] of the [[argument]], and evaluates it into a single array in right-to-left order. This operation is known as [[wikipedia:Fold (higher-order function)|Fold]], or more specifically <syntaxhighlight lang=text inline>foldr1</syntaxhighlight>, in other functional programming languages such as Haskell.


== Description ==
== Description ==


When applied to a [[vector]] argument, <source lang=apl inline>f/x</source> evaluates to the expression <source lang=text inline>a f b f c f d …</source> where <source lang=text inline>a, b, c, d, …</source> are the elements of <source lang=text inline>x</source>. In general, Reduce reduces one chosen [[axis]] (either implied by using the last-axis form <source lang=apl inline>f/</source> or first-axis <source lang=apl inline>f⌿</source>, or explicitly by using [[function axis]] <source lang=apl inline>f/[x]</source>) by evaluating each [[vector]] along the chosen axis into a [[scalar]].
When applied to a [[vector]] argument, <syntaxhighlight lang=apl inline>f/x</syntaxhighlight> evaluates to the expression <syntaxhighlight lang=text inline>a f b f c f d …</syntaxhighlight> where <syntaxhighlight lang=text inline>a, b, c, d, …</syntaxhighlight> are the elements of <syntaxhighlight lang=text inline>x</syntaxhighlight>. In general, Reduce reduces one chosen [[axis]] (either implied by using the last-axis form <syntaxhighlight lang=apl inline>f/</syntaxhighlight> or first-axis <syntaxhighlight lang=apl inline>f⌿</syntaxhighlight>, or explicitly by using [[function axis]] <syntaxhighlight lang=apl inline>f/[x]</syntaxhighlight>) by evaluating each [[vector]] along the chosen axis into a [[scalar]].


In [[nested array model]], Reduce has a strong property that the reduced axis is removed from the [[shape]] of the argument, which forces it to [[enclose]] each non-[[simple]] result in the returned array.
In [[nested array model]], Reduce has a strong property that the reduced axis is removed from the [[shape]] of the argument, which forces it to [[enclose]] each non-[[simple]] result in the returned array. It can be modeled as <syntaxhighlight lang=apl inline>f¨/</syntaxhighlight> in the leading axis model.


In [[leading axis model]], Reduce only has the first-axis form, and it reduces the [[major cell|major cells]] of the entire array, not the individual elements. It does not enclose the result either. Instead, reduction over an axis other than the first is performed via the [[Rank (operator)|Rank operator]], which [[mix|mixes]] the results into a flat array.
In [[leading axis model]], Reduce only has the first-axis form, and it reduces the [[major cell|major cells]] of the entire array, not the individual elements. It does not enclose the result either. It can be modeled as <syntaxhighlight lang=apl inline>↑∘(f⌿)∘(⊂⍤¯1)</syntaxhighlight> in the nested array model. Reduction over an axis other than the first is performed via the [[Rank (operator)|Rank operator]], which [[mix|mixes]] the results into a flat array.


== Examples ==
== Examples ==
Line 13: Line 13:
Reduce is mainly used for aggregation, such as sum (using [[Add]]) or product (using [[Times]]). If used with [[Subtract]], it computes the alternating sum, since <math>a-(b-(c-(d-\cdots))) = a-b+c-d+\cdots</math>. Using with [[Divide]] gives similar effect, returning the alternating product <math>a\div(b\div(c\div(d\div\cdots))) = a\div b\times c\div d\times\cdots</math>.
Reduce is mainly used for aggregation, such as sum (using [[Add]]) or product (using [[Times]]). If used with [[Subtract]], it computes the alternating sum, since <math>a-(b-(c-(d-\cdots))) = a-b+c-d+\cdots</math>. Using with [[Divide]] gives similar effect, returning the alternating product <math>a\div(b\div(c\div(d\div\cdots))) = a\div b\times c\div d\times\cdots</math>.


<source lang=apl>
<syntaxhighlight lang=apl>
       +/1 2 3 4 5
       +/1 2 3 4 5
15
15
Line 22: Line 22:
       ÷/1 2 3 4 5
       ÷/1 2 3 4 5
1.875
1.875
</source>
</syntaxhighlight>


Reduction by [[Minimum]] or [[Maximum]] gives the minimum or maximum over several numbers. Same goes for [[And]], [[Or]], [[GCD]], [[LCM]], and XOR ([[Not Equal]] on [[Booleans]]).
Reduction by [[Minimum]] or [[Maximum]] gives the minimum or maximum over several numbers. Same goes for [[And]], [[Or]], [[GCD]], [[LCM]], and XOR ([[Not Equal]] on [[Booleans]]).


Although Reduce is <source lang=text inline>foldr1</source> in nature, one can use it like <source lang=text inline>foldr</source>, where a designated starting value is modified by the rest of the values in sequence. In this case, the start value (enclosed if not a [[simple scalar]]) is attached to the right end of the [[vector]] of "modifiers", and then the entire vector is reduced.
Although Reduce is <syntaxhighlight lang=text inline>foldr1</syntaxhighlight> in nature, one can use it like <syntaxhighlight lang=text inline>foldr</syntaxhighlight>, where a designated starting value is modified by the rest of the values in sequence. In this case, the start value (enclosed if not a [[simple scalar]]) is attached to the right end of the [[vector]] of "modifiers", and then the entire vector is reduced.


<source lang=apl>
<syntaxhighlight lang=apl>
       (⍉∘⌽↓)/2 1 2 1,⊂5 6⍴⍳30  ⍝ Trim a matrix from all four sides, by rotating the matrix after each trim
       (⍉∘⌽↓)/2 1 2 1,⊂5 6⍴⍳30  ⍝ Trim a matrix from all four sides, by rotating the matrix after each trim
┌─────┐
┌─────┐
Line 39: Line 39:
│1 0.9682458366 0.8660254038 0.6614378278 0│
│1 0.9682458366 0.8660254038 0.6614378278 0│
└──────────────────────────────────────────┘
└──────────────────────────────────────────┘
</source>
</syntaxhighlight>


Reduction over an empty axis gives the [[identity element]] of the operand.
Reduction over an empty axis gives the [[identity element]] of the operand.


<source lang=apl>
<syntaxhighlight lang=apl>
       +/⍬
       +/⍬
0
0
Line 49: Line 49:
0 0 0
0 0 0
0 0 0
0 0 0
</source>
</syntaxhighlight>


[[FinnAPL idiom library]] contains over 100 entries which use Reduce in some way.
[[FinnAPL idiom library]] contains over 100 entries which use Reduce in some way.

Latest revision as of 19:11, 26 June 2023

/

Reduce (/, ), also called Reduction or Insert, is a primitive monadic operator which takes a dyadic function operand, inserts it between the elements of the argument, and evaluates it into a single array in right-to-left order. This operation is known as Fold, or more specifically foldr1, in other functional programming languages such as Haskell.

Description

When applied to a vector argument, f/x evaluates to the expression a f b f c f d … where a, b, c, d, … are the elements of x. In general, Reduce reduces one chosen axis (either implied by using the last-axis form f/ or first-axis f⌿, or explicitly by using function axis f/[x]) by evaluating each vector along the chosen axis into a scalar.

In nested array model, Reduce has a strong property that the reduced axis is removed from the shape of the argument, which forces it to enclose each non-simple result in the returned array. It can be modeled as f¨/ in the leading axis model.

In leading axis model, Reduce only has the first-axis form, and it reduces the major cells of the entire array, not the individual elements. It does not enclose the result either. It can be modeled as ↑∘(f⌿)∘(⊂⍤¯1) in the nested array model. Reduction over an axis other than the first is performed via the Rank operator, which mixes the results into a flat array.

Examples

Reduce is mainly used for aggregation, such as sum (using Add) or product (using Times). If used with Subtract, it computes the alternating sum, since . Using with Divide gives similar effect, returning the alternating product .

      +/1 2 3 4 5
15
      ×/1 2 3 4 5
120
      -/1 2 3 4 5
3
      ÷/1 2 3 4 5
1.875

Reduction by Minimum or Maximum gives the minimum or maximum over several numbers. Same goes for And, Or, GCD, LCM, and XOR (Not Equal on Booleans).

Although Reduce is foldr1 in nature, one can use it like foldr, where a designated starting value is modified by the rest of the values in sequence. In this case, the start value (enclosed if not a simple scalar) is attached to the right end of the vector of "modifiers", and then the entire vector is reduced.

      (⍉∘⌽↓)/2 1 2 1,⊂5 6⍴⍳30  ⍝ Trim a matrix from all four sides, by rotating the matrix after each trim
┌─────┐
│ 9 10│
│15 16│
│21 22│
└─────┘
      ○/1 ¯2,⊂0 0.25 0.5 0.75 1  ⍝ sin∘arccos of multiple values
┌──────────────────────────────────────────┐
│1 0.9682458366 0.8660254038 0.6614378278 0│
└──────────────────────────────────────────┘

Reduction over an empty axis gives the identity element of the operand.

      +/⍬
0
      +/2 3 0⍴0
0 0 0
0 0 0

FinnAPL idiom library contains over 100 entries which use Reduce in some way.

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