| 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 | }}} |