-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
72e3627
commit 9b7afa9
Showing
1 changed file
with
89 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,96 @@ | ||
# Julia Base Broadcast Background | ||
|
||
Please see the official Julia [broadcasting documentation] | ||
Here, we'll provide our own brief background of Julia Base's broadcast | ||
machinery. Please see the official Julia [broadcasting documentation] | ||
(https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting), for more | ||
information. | ||
|
||
Here, we'll give a brief background of Julia Base's broadcast machinery. | ||
## Introduction | ||
|
||
## From parse time to runtime | ||
Sometimes, you need to perform operations on arrays of different sizes, like | ||
adding a vector to each column of a matrix. One inefficient approach would be | ||
to expand the vector to match the matrix size: | ||
|
||
```julia | ||
julia> a = rand(2, 1); A = rand(2, 3); | ||
|
||
julia> repeat(a, 1, 3) + A | ||
2×3 Array{Float64,2}: | ||
1.20813 1.82068 1.25387 | ||
1.56851 1.86401 1.67846 | ||
``` | ||
|
||
This can be inefficient with large arrays, so Julia offers the broadcast | ||
function. It automatically expands smaller dimensions in the arrays to match | ||
the larger ones without using extra memory and applies the operation element by | ||
element: | ||
|
||
```julia | ||
julia> broadcast(+, a, A) | ||
2×3 Array{Float64,2}: | ||
1.20813 1.82068 1.25387 | ||
1.56851 1.86401 1.67846 | ||
|
||
julia> b = rand(1,2) | ||
1×2 Array{Float64,2}: | ||
0.867535 0.00457906 | ||
|
||
julia> broadcast(+, a, b) | ||
2×2 Array{Float64,2}: | ||
1.71056 0.847604 | ||
1.73659 0.873631 | ||
``` | ||
|
||
Operators like `.+` and `.*` are shorthand for broadcast calls (with the added | ||
benefit of "fusing" the operations). The `broadcast!` function lets you specify | ||
where to store the result (and you can use `.=` to do this in a similar fused | ||
way). For example, `f.(args...)` is the same as `broadcast(f, args...)`, | ||
offering a simpler syntax for broadcasting any function. Also, nested "dot | ||
calls" like `f.(...)` automatically fuse into a single broadcast call. | ||
|
||
Broadcasting isn't limited to arrays — it also works with scalars, tuples, and | ||
other collections. By default, only certain types are treated as scalars, such | ||
as `Number`s, `String`s, `Symbol`s, `Type`s, `Function`s, and common singletons | ||
like `missing` and `nothing`. Other types are treated element by element. | ||
|
||
```julia | ||
julia> convert.(Float32, [1, 2]) | ||
2-element Vector{Float32}: | ||
1.0 | ||
2.0 | ||
|
||
julia> ceil.(UInt8, [1.2 3.4; 5.6 6.7]) | ||
2×2 Matrix{UInt8}: | ||
0x02 0x04 | ||
0x06 0x07 | ||
|
||
julia> string.(1:3, ". ", ["First", "Second", "Third"]) | ||
3-element Vector{String}: | ||
"1. First" | ||
"2. Second" | ||
"3. Third" | ||
``` | ||
|
||
If you want to prevent a container (like an array) from being iterated over | ||
during broadcasting, you can wrap it in another container (like a | ||
single-element `Tuple`). This will make it behave as a single value during the | ||
broadcast. | ||
|
||
```julia | ||
julia> ([1, 2, 3], [4, 5, 6]) .+ ([1, 2, 3],) | ||
([2, 4, 6], [5, 7, 9]) | ||
|
||
julia> ([1, 2, 3], [4, 5, 6]) .+ tuple([1, 2, 3]) | ||
([2, 4, 6], [5, 7, 9]) | ||
``` | ||
|
||
## `@.` syntax | ||
|
||
Julia Base also provides a macro, `@.`, which converts every function call or | ||
operator in `expr` into a "dot call" (e.g. convert `f(x)` to `f.(x)`), and converts | ||
every assignment in `expr` to a "dot assignment" (e.g. convert `+=` to `.+=`). | ||
|
||
If you want to avoid adding dots for selected function calls in expr, splice | ||
those function calls in with `$`. For example, `@. sqrt(abs($sort(x)))` is | ||
equivalent to `sqrt.(abs.(sort(x)))` (no dot for sort). | ||
|
||
TODO |