Skip to content

Commit e741a5a

Browse files
committed
allow multidimensional filled rotate
1 parent 74e91e4 commit e741a5a

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

src/algorithm/dyadic/mod.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,19 @@ impl<T: ArrayValue> Array<T> {
11071107
if !forward && env.scalar_unfill::<T>().is_ok() {
11081108
return Err(env.error("Cannot invert filled rotation"));
11091109
}
1110-
let fill = env.scalar_fill::<T>().ok();
1110+
let fill = env.array_fill::<T>().ok().map(|fv| fv.value);
1111+
if let Some(fill) = &fill {
1112+
let by_dims = by.shape.last().copied().unwrap_or(1);
1113+
let end_dims = &self.shape[self.rank().min(depth + by_dims)..];
1114+
if fill.rank() > end_dims.len() || !end_dims.ends_with(&fill.shape) {
1115+
return Err(env.error(format!(
1116+
"Rotated rows each have shape {}, \
1117+
but the fill value has incompatible shape {}",
1118+
FormatShape(end_dims),
1119+
fill.shape
1120+
)));
1121+
}
1122+
}
11111123

11121124
// Expand the array if doing multiple rotations
11131125
if self.rank() > by.rank() && self.shape.contains(&1) {
@@ -1144,7 +1156,7 @@ impl<T: ArrayValue> Array<T> {
11441156
shape: &[usize],
11451157
rotated: &mut [T],
11461158
depth: usize,
1147-
fill: Option<&T>,
1159+
fill: Option<&[T]>,
11481160
env: &Uiua,
11491161
) -> UiuaResult {
11501162
if by.is_empty() || rotated.is_empty() {
@@ -1205,7 +1217,7 @@ impl<T: ArrayValue> Array<T> {
12051217
&self.shape,
12061218
self.data.as_mut_slice(),
12071219
depth,
1208-
fill.as_ref().map(|fv| &fv.value),
1220+
fill.as_ref().map(|fv| fv.data.as_slice()),
12091221
env,
12101222
)?;
12111223

@@ -1225,10 +1237,10 @@ impl<T: ArrayValue> Array<T> {
12251237
}
12261238
}
12271239

1228-
fn rotate_maybe_fill<T: Clone>(by: &[isize], shape: &[usize], data: &mut [T], fill: Option<&T>) {
1240+
fn rotate_maybe_fill<T: Clone>(by: &[isize], shape: &[usize], data: &mut [T], fill: Option<&[T]>) {
12291241
rotate(by, shape, data);
12301242
if let Some(fill) = fill {
1231-
fill_shift(by, shape, data, fill.clone());
1243+
fill_shift(by, shape, data, fill);
12321244
}
12331245
}
12341246

@@ -1257,7 +1269,7 @@ fn rotate<T>(by: &[isize], shape: &[usize], data: &mut [T]) {
12571269
}
12581270
}
12591271

1260-
fn fill_shift<T: Clone>(by: &[isize], shape: &[usize], data: &mut [T], fill: T) {
1272+
fn fill_shift<T: Clone>(by: &[isize], shape: &[usize], data: &mut [T], fill: &[T]) {
12611273
if by.is_empty() || shape.is_empty() {
12621274
return;
12631275
}
@@ -1270,13 +1282,17 @@ fn fill_shift<T: Clone>(by: &[isize], shape: &[usize], data: &mut [T], fill: T)
12701282
if offset != 0 {
12711283
let abs_offset = offset.unsigned_abs() * row_len;
12721284
let data_len = data.len();
1273-
if offset > 0 {
1274-
for val in &mut data[data_len.saturating_sub(abs_offset)..] {
1275-
*val = fill.clone();
1276-
}
1277-
} else {
1278-
for val in &mut data[..abs_offset.min(data_len)] {
1279-
*val = fill.clone();
1285+
if !fill.is_empty() {
1286+
if offset > 0 {
1287+
for slice in
1288+
data[data_len.saturating_sub(abs_offset)..].chunks_exact_mut(fill.len())
1289+
{
1290+
slice.clone_from_slice(fill);
1291+
}
1292+
} else {
1293+
for slice in data[..abs_offset.min(data_len)].chunks_exact_mut(fill.len()) {
1294+
slice.clone_from_slice(fill);
1295+
}
12801296
}
12811297
}
12821298
}
@@ -1286,7 +1302,7 @@ fn fill_shift<T: Clone>(by: &[isize], shape: &[usize], data: &mut [T], fill: T)
12861302
return;
12871303
}
12881304
for cell in data.chunks_mut(row_len) {
1289-
fill_shift(index, shape, cell, fill.clone());
1305+
fill_shift(index, shape, cell, fill);
12901306
}
12911307
}
12921308

tests/dyadic.ua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
⍤⤙≍ [2 3 0] ⬚0 ↻1 [1 2 3]
5757
⍤⤙≍ [3 4 5 0 0] ⬚0↻ 2 [1 2 3 4 5]
5858
⍤⤙≍ [0 0 1 2 3] ⬚0↻ ¯2 [1 2 3 4 5]
59-
⍤⤙≍ [2 3 1] ⬚0⬚[] ↻1 [1 2 3]
6059
⍤⤙≍ [] ↻1[]
6160
⍤⤙≍ [] ↻0_1[]
6261
⍤⤙≍ [] ↻1_1[]
@@ -70,6 +69,11 @@
7069
⍤⤙≍ [2 3 4 0] ⬚0↻1 [1 2 3 4]
7170
⍤⤙≍ [0 1 2 3] ⬚0⌝↻1 [1 2 3 4]
7271
⍤⤙≍ [0_1 1_0 0_1 1_0 0_1] ≡↻ ⇡5 °△1_2
72+
⍤⤙≍ °△3_0 ⬚[]↻1 [[][][]]
73+
⍤⤙≍ [2 3 4 τ τ] ⬚τ↻₂ ⇡5
74+
⍤⤙≍ [2_2 3_3 4_4 π_τ π_τ] ⬚π_τ↻2 ⍉˙⊟ ⇡5
75+
⍤⤙≍ ⬚0[7_8_9_0_0 12_13_14 17_18_19 0] ⬚0↻ 1_2 ↯4_5⇡20
76+
⍤⤙≍ [[8_9 10_11 π_τ] [14_15 16_17 π_τ] [π_τ π_τ π_τ]] ⬚π_τ↻ 1_1 °△3_3_2
7377

7478
# Take and drop
7579
⍤⤙≍ [1] ↙1 [1 2 3 4]

0 commit comments

Comments
 (0)