Wed, 22 Dec 2021 11:14:38 +0200
Add metaprogramming tools and fast multidimensional loops.
35
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
1 | ############################### |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
2 | # Fast multi-dimensional loops |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
3 | ############################### |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
4 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
5 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
6 | `module AlgTools.Loops` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
7 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
8 | This module implements `for_zip`, `for_indices`, and `for_linspace` generated |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
9 | functions for loops amenable to a high level of optimisation by the compiler. |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
10 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
11 | module Loops |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
12 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
13 | using ..Metaprogramming |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
14 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
15 | ############## |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
16 | # Our exports |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
17 | ############## |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
18 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
19 | export Box, |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
20 | Grid, |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
21 | @Grid_str, |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
22 | for_zip, |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
23 | for_indices, |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
24 | for_linspace |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
25 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
26 | ##################################### |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
27 | # Looping over many iterators/arrays |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
28 | ##################################### |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
29 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
30 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
31 | `for_zip(f, a...)` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
32 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
33 | With `dims` of type `Dims{N}`, loop over all `(i_1,…,i_N)` with `i_j ∈ 1:dims[j]`. |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
34 | Typically to be used as |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
35 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
36 | ```julia |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
37 | for_zip(a, b) do x, y |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
38 | # do something |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
39 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
40 | ``` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
41 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
42 | @generated function for_zip(f :: Function, a...) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
43 | # Generate reference variables to avoid execution of potential |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
44 | # code inputs several times. |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
45 | aref = [gensym("aref_$(j)") for j ∈ 1:length(a)] |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
46 | # Generate length-checking asserts |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
47 | asserts = ( :( length($b)==M ) for b ∈ aref[2:end] ) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
48 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
49 | quote |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
50 | # Assign input expressions to reference variables |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
51 | local $(lift_exprs(aref)) = (a...,) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
52 | # Check that all inputs are of equal length |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
53 | M = length($(aref[1])) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
54 | @assert $(all_exprs(asserts)) "Parameter lengths have to be equal" |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
55 | # Do the loop |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
56 | for i = 1:M |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
57 | f($([ :( $c[i] ) for c ∈ aref]...)) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
58 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
59 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
60 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
61 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
62 | ####################### |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
63 | # Looping over indices |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
64 | ####################### |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
65 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
66 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
67 | `for_indices(f, N, dims)` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
68 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
69 | With `dims` of type `Dims{N}`, loop over all `(i_1,…,i_N)` with `i_j ∈ 1:dims[j]`. |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
70 | Typically to be used as |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
71 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
72 | ```julia |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
73 | for_indices(N, dims) do i_1, …, i_N |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
74 | # do something |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
75 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
76 | ``` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
77 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
78 | @generated function for_indices(f :: Function, dims :: Dims{N}) where N |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
79 | # This depends on numbers being passed as numbers, not Exprs! |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
80 | local i = [gensym("i_$(j)") for j ∈ 1:N] |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
81 | local di = [gensym("di_$(j)") for j ∈ 1:N] |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
82 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
83 | local expr = :( f($(i...),) ) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
84 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
85 | for j = 1:N |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
86 | expr = quote |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
87 | for $(i[j]) = 1:$(di[j]) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
88 | $expr |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
89 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
90 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
91 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
92 | quote |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
93 | $(lift_exprs(di)) = dims |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
94 | $expr |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
95 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
96 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
97 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
98 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
99 | ########################################## |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
100 | # Looping over indices and transformation |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
101 | ########################################## |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
102 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
103 | Box{N, T} = NTuple{N, Tuple{T, T}} |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
104 | struct Grid{R} end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
105 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
106 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
107 | `@Grid_str` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
108 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
109 | A convenience macro for writing Grid{:gridtype} as Grid"gridtype" for use with `for_linspace`. |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
110 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
111 | macro Grid_str(s) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
112 | :(Grid{$(Expr(:quote, Symbol(s)))}) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
113 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
114 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
115 | # For type-checking user's code, it would be better to wrap `for_linspace` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
116 | # with a multiple dispatch type-case selector. However, the approach of |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
117 | # avoiding a wrapper and calling `gridalign` from `for_linspace` to get |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
118 | # the grid parements helps with inlining the code. |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
119 | @inline gridalign(:: Type{Type{Grid{:midpoint}}}) = (0.5, 0) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
120 | @inline gridalign(:: Type{Type{Grid{:firstpoint}}}) = (1.0, 0) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
121 | @inline gridalign(:: Type{Type{Grid{:lastpoint}}}) = (0.0, 0) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
122 | @inline gridalign(:: Type{Type{Grid{:linspace}}}) = (1.0, 1) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
123 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
124 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
125 | `for_linspace(f :: Function, dims :: Dims{N} , box :: Box{N, T}, grid :: Type{Grid{G}} = Grid"linspace")` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
126 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
127 | With `box` of type `Box{N, T} = NTuple{N, Tuple{T, T}}` with `T <: AbstractFloat`, |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
128 | loop over all `((i_1,…,i_N), (x_1,…,x_N))` with `i_j ∈ 1:dims[j]` and each `x_i` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
129 | sampled in equal-length subintervals of the interval `box[i]`. |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
130 | If `grid` is `Grid"midpoint"`, `Grid"firstpoint"`, `Grid"lastpoint"`, the point `x_i` is |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
131 | the mid-point, first point, or last point of the corresponding subinterval, and there |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
132 | are `dims[j]` subintervals. If `grid` is `Grid"linspace"`, there are `dims[j]-1` subintervals, |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
133 | and all the endpoints are generated. Typically to be used as |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
134 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
135 | ```julia |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
136 | for_linspace(dims, box) do (i_1, …, i_N), (x_1, …, x_N) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
137 | # do something |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
138 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
139 | ``` |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
140 | """ |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
141 | @inline @generated function |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
142 | for_linspace(f :: Function, dims :: Dims{N}, box :: Box{N, T}, |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
143 | grid :: Type{Grid{G}} = Grid"linspace") where {N, T <: AbstractFloat, G} |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
144 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
145 | shift, extrapoints = gridalign(grid) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
146 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
147 | # Generate some local variables of primitive types, storable in registers |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
148 | i = [gensym("i_$j") for j ∈ 1:N] |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
149 | c = [gensym("c_$j") for j ∈ 1:N] |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
150 | d = [gensym("d_$j") for j ∈ 1:N] |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
151 | n = [gensym("n_$j") for j ∈ 1:N] |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
152 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
153 | # Function call |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
154 | x = (:( $(i[j])*$(c[j])+$(d[j]) ) for j ∈ 1:N) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
155 | expr = :( f( ($(i...),), ($(x...),) ) ) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
156 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
157 | # Main recursion |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
158 | for j = 1:N |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
159 | expr = quote |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
160 | for $(i[j]) = 1:$(n[j]) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
161 | $expr |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
162 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
163 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
164 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
165 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
166 | # Initialisation of linear transformation and variable references |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
167 | asserts = ( :( @assert ($(n[j]) > extrapoints) "Dimension $j too small" ) for j ∈ 1:N ) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
168 | scales = ( :( (box[$j][2]-box[$j][1])/($(n[j])-extrapoints) ) for j ∈ 1:N ) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
169 | translates = ( :( box[$j][1] - shift*$(c[j]) ) for j ∈ 1:N ) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
170 | expr = quote |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
171 | # Set up local (register-storable) variables for dims, needed in the loop above |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
172 | local $(lift_exprs(n)) = dims |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
173 | # Check everything is ok |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
174 | $(sequence_exprs(asserts)) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
175 | # Set up linear transformation, needed in the loop above |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
176 | local $(lift_exprs(c)) = $(lift_exprs(scales)) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
177 | local $(lift_exprs(d)) = $(lift_exprs(translates)) |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
178 | # Execute the loop |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
179 | $expr |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
180 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
181 | end |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
182 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
183 | |
d881275c6564
Add metaprogramming tools and fast multidimensional loops.
Tuomo Valkonen <tuomov@iki.fi>
parents:
diff
changeset
|
184 | end # module |