119 | | |
| 125 | Given this definition, the type of `select` now becomes |
| 126 | {{{ |
| 127 | select:: (U.Elt e, Shape dim, Shape dim') => Array dim e -> SelectIndex dim dim' -> Array dim' e |
| 128 | }}} |
| 129 | Example: |
| 130 | {{{ |
| 131 | arr:: Array DIM3 Double |
| 132 | select arr (IndexFixed 3 (IndexAll (IndexAll IndexNil))) |
| 133 | }}} |
| 134 | The index type is also used to express the type of generalised replicate: |
| 135 | {{{ |
| 136 | replicate:: Array dim' e -> SelectIndex dim dim' -> Array dim e |
| 137 | }}} |
| 138 | Even though the index type serves well to express the relationship |
| 139 | between the selector/multiplicator and the dimensionality of the |
| 140 | argument and the result array, it is somehow inconvenient to use, as |
| 141 | the examples demonstrate. This is therefore another example where we |
| 142 | need to add another layer to improve the usability of the library. |
| 148 | == Array Operations == |
| 149 | |
| 150 | Backpermute and default backpermute are two general operations which allow |
| 151 | the programmer to express all structural operations which reorder or extract |
| 152 | elements based on their position in the argument array: |
| 153 | {{{ |
| 154 | backpermute:: (U.Elt e, Shape dim, Shape dim') => |
| 155 | Array dim e -> dim' -> (dim' -> dim) -> Array dim' e |
| 156 | |
| 157 | backpermuteDft::(U.Elt e, Shape dim, Shape dim') => |
| 158 | Array dim e -> e -> dim' -> (dim' -> Maybe dim) -> Array dim' e |
| 159 | }}} |
| 160 | |
| 161 | |
| 162 | {{{ |
| 163 | map:: (U.Elt a, U.Elt b, Shape dim) => (a -> b) -> Array dim a -> Array dim b |
| 164 | |
| 165 | zip:: (U.Elt a, U.Elt b, Shape dim) => Array dim a -> Array dim b-> Array dim (a :*: b) |
| 166 | |
| 167 | zipWith:: (U.Elt a, U.Elt b, U.Elt c, Shape dim) => |
| 168 | (a -> b -> c) -> Array dim a -> Array dim b-> Array dim c |
| 169 | |
| 170 | mapFold:: (U.Elt e, Shape dim) => (e -> e-> e) -> e -> Array (dim :*: Int) e -> Array dim e |
| 171 | |
| 172 | reshape:: (Shape dim', Shape dim, U.Elt e) => Array dim e -> dim' -> Array dim' e |
| 173 | }}} |
| 174 | |
| 175 | The following operations could be (and in the sequential implementation indeed are) expressed |
| 176 | in terms of backpermute and default backpermute. However, a programmer should aim at using more |
| 177 | specialised functions when provided, as they carry more information about the pattern of reordering. |
| 178 | In particular in the parallel case, this could be used to provide significantly more efficient |
| 179 | implementation which make use of locality and communication patterns. |
| 180 | {{{ |
| 181 | shift:: (Shape dim, U.Elt e) => Array dim e -> e -> dim -> Array dim e |
| 182 | |
| 183 | rotate:: (Shape dim, U.Elt e) => Array dim e -> e -> dim -> Array dim e |
| 184 | |
| 185 | tile:: (Shape dim, U.Elt e) => Array dim e -> dim -> dim -> Array dim e |
| 186 | }}} |