library("broadcast")
# maths ====
<- 1:10
x broadcaster(x) <- TRUE
<- 1:10
y broadcaster(y) <- TRUE
+ y / x
x ## [1] 2 3 4 5 6 7 8 9 10 11
## broadcaster
+ 1 # mathematically equivalent to the above, since x == y
x ## [1] 2 3 4 5 6 7 8 9 10 11
## broadcaster
+ y) / x
(x ## [1] 2 2 2 2 2 2 2 2 2 2
## broadcaster
2 * x/x # mathematically equivalent to the above, since x == y
## [1] 2 2 2 2 2 2 2 2 2 2
## broadcaster
dim(x) <- c(10, 1)
dim(y) <- c(1, 10)
+ y / x
x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## [1,] 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000
## [2,] 2.500000 3.000000 3.500000 4.000000 4.500000 5.000000 5.500000
## [3,] 3.333333 3.666667 4.000000 4.333333 4.666667 5.000000 5.333333
## [4,] 4.250000 4.500000 4.750000 5.000000 5.250000 5.500000 5.750000
## [5,] 5.200000 5.400000 5.600000 5.800000 6.000000 6.200000 6.400000
## [6,] 6.166667 6.333333 6.500000 6.666667 6.833333 7.000000 7.166667
## [7,] 7.142857 7.285714 7.428571 7.571429 7.714286 7.857143 8.000000
## [8,] 8.125000 8.250000 8.375000 8.500000 8.625000 8.750000 8.875000
## [9,] 9.111111 9.222222 9.333333 9.444444 9.555556 9.666667 9.777778
## [10,] 10.100000 10.200000 10.300000 10.400000 10.500000 10.600000 10.700000
## [,8] [,9] [,10]
## [1,] 9.000000 10.000000 11.000000
## [2,] 6.000000 6.500000 7.000000
## [3,] 5.666667 6.000000 6.333333
## [4,] 6.000000 6.250000 6.500000
## [5,] 6.600000 6.800000 7.000000
## [6,] 7.333333 7.500000 7.666667
## [7,] 8.142857 8.285714 8.428571
## [8,] 9.000000 9.125000 9.250000
## [9,] 9.888889 10.000000 10.111111
## [10,] 10.800000 10.900000 11.000000
## broadcaster
+ y) / x
(x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 9.000000
## [2,] 1.500000 2.000000 2.500000 3.000000 3.500000 4.000000 4.500000 5.000000
## [3,] 1.333333 1.666667 2.000000 2.333333 2.666667 3.000000 3.333333 3.666667
## [4,] 1.250000 1.500000 1.750000 2.000000 2.250000 2.500000 2.750000 3.000000
## [5,] 1.200000 1.400000 1.600000 1.800000 2.000000 2.200000 2.400000 2.600000
## [6,] 1.166667 1.333333 1.500000 1.666667 1.833333 2.000000 2.166667 2.333333
## [7,] 1.142857 1.285714 1.428571 1.571429 1.714286 1.857143 2.000000 2.142857
## [8,] 1.125000 1.250000 1.375000 1.500000 1.625000 1.750000 1.875000 2.000000
## [9,] 1.111111 1.222222 1.333333 1.444444 1.555556 1.666667 1.777778 1.888889
## [10,] 1.100000 1.200000 1.300000 1.400000 1.500000 1.600000 1.700000 1.800000
## [,9] [,10]
## [1,] 10.000000 11.000000
## [2,] 5.500000 6.000000
## [3,] 4.000000 4.333333
## [4,] 3.250000 3.500000
## [5,] 2.800000 3.000000
## [6,] 2.500000 2.666667
## [7,] 2.285714 2.428571
## [8,] 2.125000 2.250000
## [9,] 2.000000 2.111111
## [10,] 1.900000 2.000000
## broadcaster
+ y) * x
(x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 2 3 4 5 6 7 8 9 10 11
## [2,] 6 8 10 12 14 16 18 20 22 24
## [3,] 12 15 18 21 24 27 30 33 36 39
## [4,] 20 24 28 32 36 40 44 48 52 56
## [5,] 30 35 40 45 50 55 60 65 70 75
## [6,] 42 48 54 60 66 72 78 84 90 96
## [7,] 56 63 70 77 84 91 98 105 112 119
## [8,] 72 80 88 96 104 112 120 128 136 144
## [9,] 90 99 108 117 126 135 144 153 162 171
## [10,] 110 120 130 140 150 160 170 180 190 200
## broadcaster
# relational operators ====
<- 1:10
x <- array(1:10, c(1, 10))
y broadcaster(x) <- TRUE
broadcaster(y) <- TRUE
== y
x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [2,] FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [3,] FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [4,] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [5,] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE
## [6,] FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
## [7,] FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
## [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
## [9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE
## [10,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
## broadcaster
!= y
x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [2,] TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [3,] TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [4,] TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
## [5,] TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE
## [6,] TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE
## [7,] TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE TRUE
## [8,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE TRUE
## [9,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE TRUE
## [10,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
## broadcaster
< y
x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [2,] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [3,] FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [4,] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
## [5,] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
## [6,] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE
## [7,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE
## [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
## [9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
## [10,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## broadcaster
> y
x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [2,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [3,] TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [4,] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [5,] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [6,] TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
## [7,] TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE
## [8,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE
## [9,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
## [10,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
## broadcaster
<= y
x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [2,] FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [3,] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [4,] FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## [5,] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE
## [6,] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
## [7,] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE
## [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE
## [9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
## [10,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
## broadcaster
>= y
x ## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [2,] TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [3,] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [4,] TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [5,] TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
## [6,] TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE
## [7,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE
## [8,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
## [9,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE
## [10,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
## broadcaster
Details on Broadcasted Operators
Description
Base ‘R’ comes with relational (==, !=, etc.), arithmetic (+, -, *, /, etc.), and logical/bit-wise (&, |) operators.
‘broadcast’ provides 2 ways to use these operators with broadcasting.
The first (and simple) way is to use the broadcaster class, which comes with it’s own method dispatch for the above mentioned operators.
This approach supports operator precedence, and for the average ‘R’ user, this is sufficient.
The second way is to use the large set of bc.
- functions.
These offer much greater control and more operators than the previous method, and has less risk of running into conflicting methods.
But it does not support operator precedence.
Operators Overloaded via Broadcaster Class
Sometimes broadcasting is needed in large mathematical expression, involving multiple variables, where precedence is of importance.
For example in an expression like x + y / z^y
.
For such cases, you may want to overload the base operators.
To that end, the ‘broadcast’ package provides the broadcaster class, which comes with its own method dispatch for the base operators.
If at least one of the 2 arguments of the base operators has the broadcaster
class attribute, and no other class (like bit64
) interferes, broadcasting will be used.
The following arithmetic operators have a ‘broadcaster’ method: +, -, *, /, ^, %%, %/%
The following relational operators have a ‘broadcaster’ method: ==, !=, <, >, <=, >=
And finally, the & and | operators also have a ‘broadcaster’ method.
See also the Examples section below.
Available bc.
functions
‘broadcast’ provides a set of functions for broadcasted element-wise binary operations with broadcasting.
These functions use an API similar to the outer function.
The following functions for simple operations are available:
-
bc.rel: General relational operations.
-
bc.b: Boolean (i.e. logical) operations;
-
bc.i: integer arithmetic operations;
-
bc.d: decimal arithmetic operations;
-
bc.cplx: complex arithmetic operations;
-
bc.str: string (in)equality, concatenation, and distance operations;
-
bc.raw: operations that take in arrays of type
raw
and return an array of typeraw
; -
bc.bit: BIT-WISE operations, supporting the
raw
andinteger
types; -
bc.list: apply any ‘R’ function to 2 recursive arrays with broadcasting.
Note that the bc.rel method is the primary method for relational operators (==, !=, <, >, <=, >=), and provides what most user usually need in relational operators.
The various other bc.
methods have specialized relational operators available for very specialised needs.
Attribute Handling
The bc.
functions and the overloaded operators generally do not preserve attributes, unlike the base ‘R’ operators.
Broadcasting often results in an object with more dimensions, larger dimensions, and/or larger length than the original objects.
Therefore, the names
, dimnames
, and dim
attributes often no longer fit the new object.
Moreover, some classes are only appropriate for certain dimensions or lengths.
Custom matrix classes, for example, presumes an object to have exactly 2 dimensions.
And the various classes provided by the ‘bit’ package have length-related attributes.
So even class attributes cannot be guaranteed to hold for the resulting objects.
However, the bc.
functions and the overloaded operators always preserve the "broadcaster" attribute, as this is necessary to chain together broadcasted operations.
Notice that this contrats with base ‘R’ in the following sense:
In base ‘R’, logical (&, |) and relational (==, !=, etc.) operators never preserve attributes, whereas the broadcasted equivalents do preserve the "broadcaster" attribute.
Almost all functions provided by ‘broadcast’ are S3 or S4 generics;
methods can be written for them for specific classes, so that class-specific attributes can be supported when needed.
Unary operations (i.e. + x
, - x
) return the original object, with only the sign adjusted.