1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::errors::*;
use ndarray::{RemoveAxis, Axis, Ix, Array, ArrayView, ArrayD};
use itertools::{zip, Itertools};
pub fn broadcast_ndarray<T: Clone>(value: ArrayD<T>, shape: &[usize]) -> Result<ArrayD<T>> {
if value.shape() == shape {
return Ok(value);
}
if value.len() != 1 {
let length = shape.iter().cloned().fold1(|a, b| a * b).unwrap_or(0);
bail!("{} values passed when {} were required", value.len(), length);
}
let value = value.first().unwrap();
Ok(Array::from_shape_fn(shape, |_| value.clone()))
}
pub fn get_ith_column<T: Clone + Default>(value: &ArrayD<T>, i: usize) -> Result<ArrayD<T>> {
match value.ndim() {
0 => if i == 0 { Ok(value.clone()) } else { Err("ith release does not exist".into()) },
1 => Ok(value.clone()),
2 => {
let release = slow_select(value, Axis(1), &[i]);
if release.len() == 1 {
Ok(Array::from_shape_vec(Vec::new(), vec![release.first()
.ok_or_else(|| Error::from("release must contain at least one value"))?])?
.mapv(|v| v.clone()))
} else {
Ok(release)
}
}
_ => Err("releases must be 2-dimensional or less".into())
}
}
pub fn slow_stack<A, D>(
axis: Axis,
arrays: &[ArrayView<A, D>],
) -> Result<Array<A, D>>
where
A: Clone,
A: Default,
D: RemoveAxis,
{
if arrays.is_empty() {
return Err("shape error when stacking, array is empty".into());
}
let mut res_dim = arrays[0].raw_dim();
if axis.index() >= res_dim.ndim() {
return Err("shape error when stacking, out of bounds".into());
}
let common_dim = res_dim.remove_axis(axis);
if arrays
.iter()
.any(|a| a.raw_dim().remove_axis(axis) != common_dim)
{
return Err("shape error when stacking, incompatible shape".into());
}
let stacked_dim = arrays.iter().fold(0, |acc, a| acc + a.len_of(axis));
res_dim[axis.index()] = stacked_dim;
let size = res_dim.size();
let v = (0..size).map(|_| A::default()).collect();
let mut res = match Array::from_shape_vec(res_dim, v) {
Ok(v) => v, Err(_) => return Err("shape error when stacking, could not create array from shape vec".into())
};
{
let mut assign_view = res.view_mut();
for array in arrays {
let len = array.len_of(axis);
let (mut front, rest) = assign_view.split_at(axis, len);
front.assign(array);
assign_view = rest;
}
}
Ok(res)
}
pub fn slow_select<A, D>(data: &Array<A, D>, axis: Axis, indices: &[Ix]) -> Array<A, D>
where
A: Default,
A: Clone,
D: RemoveAxis,
{
let mut subs = vec![data.view(); indices.len()];
for (&i, sub) in zip(indices, &mut subs[..]) {
sub.collapse_axis(axis, i);
}
if subs.is_empty() {
let mut dim = data.raw_dim();
dim[axis.index()] = 0;
Array::from_shape_vec(dim, vec![]).unwrap()
} else {
slow_stack(axis, &subs).unwrap()
}
}