Skip to content

Commit 255127a

Browse files
committed
Remove some more allocations
1 parent 4ea183b commit 255127a

File tree

3 files changed

+67
-51
lines changed

3 files changed

+67
-51
lines changed

src/linalg/basic/vector.rs

+20
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,25 @@ pub struct VecView<'a, T: Debug + Display + Copy + Sized> {
1515
ptr: &'a [T],
1616
}
1717

18+
impl<T: Debug + Display + Copy + Sized> Array<T, usize> for &[T] {
19+
fn get(&self, i: usize) -> &T {
20+
&self[i]
21+
}
22+
23+
fn shape(&self) -> usize {
24+
self.len()
25+
}
26+
27+
fn is_empty(&self) -> bool {
28+
self.len() > 0
29+
}
30+
31+
fn iterator<'b>(&'b self, axis: u8) -> Box<dyn Iterator<Item = &'b T> + 'b> {
32+
assert!(axis == 0, "For one dimensional array `axis` should == 0");
33+
Box::new(self.iter())
34+
}
35+
}
36+
1837
impl<T: Debug + Display + Copy + Sized> Array<T, usize> for Vec<T> {
1938
fn get(&self, i: usize) -> &T {
2039
&self[i]
@@ -46,6 +65,7 @@ impl<T: Debug + Display + Copy + Sized> MutArray<T, usize> for Vec<T> {
4665
}
4766

4867
impl<T: Debug + Display + Copy + Sized> ArrayView1<T> for Vec<T> {}
68+
impl<T: Debug + Display + Copy + Sized> ArrayView1<T> for &[T] {}
4969

5070
impl<T: Debug + Display + Copy + Sized> MutArrayView1<T> for Vec<T> {}
5171

src/svm/svc.rs

+40-42
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,12 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX> + 'a, Y: Array
336336
fn predict_for_row(&self, x: &[TX]) -> TX {
337337
let mut f = self.b.unwrap();
338338

339+
let xi: Vec<_> = x.iter().map(|e| e.to_f64().unwrap()).collect();
339340
for i in 0..self.instances.as_ref().unwrap().len() {
341+
let xj: Vec<_> = self.instances.as_ref().unwrap()[i]
342+
.iter()
343+
.map(|e| e.to_f64().unwrap())
344+
.collect();
340345
f += self.w.as_ref().unwrap()[i]
341346
* TX::from(
342347
self.parameters
@@ -345,13 +350,7 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX> + 'a, Y: Array
345350
.kernel
346351
.as_ref()
347352
.unwrap()
348-
.apply(
349-
&x.iter().map(|e| e.to_f64().unwrap()).collect(),
350-
&self.instances.as_ref().unwrap()[i]
351-
.iter()
352-
.map(|e| e.to_f64().unwrap())
353-
.collect(),
354-
)
353+
.apply(&xi, &xj)
355354
.unwrap(),
356355
)
357356
.unwrap();
@@ -544,15 +543,14 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
544543
let mut cache_values: Vec<((usize, usize), TX)> = Vec::new();
545544

546545
for v in self.sv.iter() {
546+
let xi: Vec<_> = v.x.iter().map(|e| e.to_f64().unwrap()).collect();
547+
let xj: Vec<_> = x.iter().map(|e| e.to_f64().unwrap()).collect();
547548
let k = self
548549
.parameters
549550
.kernel
550551
.as_ref()
551552
.unwrap()
552-
.apply(
553-
&v.x.iter().map(|e| e.to_f64().unwrap()).collect(),
554-
&x.iter().map(|e| e.to_f64().unwrap()).collect(),
555-
)
553+
.apply(&xi, &xj)
556554
.unwrap();
557555
cache_values.push(((i, v.index), TX::from(k).unwrap()));
558556
g -= v.alpha * k;
@@ -571,7 +569,7 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
571569
cache.insert(v.0, v.1.to_f64().unwrap());
572570
}
573571

574-
let x_f64 = x.iter().map(|e| e.to_f64().unwrap()).collect();
572+
let x_f64: Vec<_> = x.iter().map(|e| e.to_f64().unwrap()).collect();
575573
let k_v = self
576574
.parameters
577575
.kernel
@@ -694,8 +692,10 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
694692
let km = sv1.k;
695693
let gm = sv1.grad;
696694
let mut best = 0f64;
695+
let xi: Vec<_> = sv1.x.iter().map(|e| e.to_f64().unwrap()).collect();
697696
for i in 0..self.sv.len() {
698697
let v = &self.sv[i];
698+
let xj: Vec<_> = v.x.iter().map(|e| e.to_f64().unwrap()).collect();
699699
let z = v.grad - gm;
700700
let k = cache.get(
701701
sv1,
@@ -704,10 +704,7 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
704704
.kernel
705705
.as_ref()
706706
.unwrap()
707-
.apply(
708-
&sv1.x.iter().map(|e| e.to_f64().unwrap()).collect(),
709-
&v.x.iter().map(|e| e.to_f64().unwrap()).collect(),
710-
)
707+
.apply(&xi, &xj)
711708
.unwrap(),
712709
);
713710
let mut curv = km + v.k - 2f64 * k;
@@ -725,6 +722,12 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
725722
}
726723
}
727724

725+
let xi: Vec<_> = self.sv[idx_1]
726+
.x
727+
.iter()
728+
.map(|e| e.to_f64().unwrap())
729+
.collect::<Vec<_>>();
730+
728731
idx_2.map(|idx_2| {
729732
(
730733
idx_1,
@@ -735,16 +738,12 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
735738
.as_ref()
736739
.unwrap()
737740
.apply(
738-
&self.sv[idx_1]
739-
.x
740-
.iter()
741-
.map(|e| e.to_f64().unwrap())
742-
.collect(),
741+
&xi,
743742
&self.sv[idx_2]
744743
.x
745744
.iter()
746745
.map(|e| e.to_f64().unwrap())
747-
.collect(),
746+
.collect::<Vec<_>>(),
748747
)
749748
.unwrap()
750749
}),
@@ -758,8 +757,11 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
758757
let km = sv2.k;
759758
let gm = sv2.grad;
760759
let mut best = 0f64;
760+
761+
let xi: Vec<_> = sv2.x.iter().map(|e| e.to_f64().unwrap()).collect();
761762
for i in 0..self.sv.len() {
762763
let v = &self.sv[i];
764+
let xj: Vec<_> = v.x.iter().map(|e| e.to_f64().unwrap()).collect();
763765
let z = gm - v.grad;
764766
let k = cache.get(
765767
sv2,
@@ -768,10 +770,7 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
768770
.kernel
769771
.as_ref()
770772
.unwrap()
771-
.apply(
772-
&sv2.x.iter().map(|e| e.to_f64().unwrap()).collect(),
773-
&v.x.iter().map(|e| e.to_f64().unwrap()).collect(),
774-
)
773+
.apply(&xi, &xj)
775774
.unwrap(),
776775
);
777776
let mut curv = km + v.k - 2f64 * k;
@@ -790,6 +789,12 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
790789
}
791790
}
792791

792+
let xj: Vec<_> = self.sv[idx_2]
793+
.x
794+
.iter()
795+
.map(|e| e.to_f64().unwrap())
796+
.collect();
797+
793798
idx_1.map(|idx_1| {
794799
(
795800
idx_1,
@@ -804,12 +809,8 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
804809
.x
805810
.iter()
806811
.map(|e| e.to_f64().unwrap())
807-
.collect(),
808-
&self.sv[idx_2]
809-
.x
810-
.iter()
811-
.map(|e| e.to_f64().unwrap())
812-
.collect(),
812+
.collect::<Vec<_>>(),
813+
&xj,
813814
)
814815
.unwrap()
815816
}),
@@ -828,12 +829,12 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
828829
.x
829830
.iter()
830831
.map(|e| e.to_f64().unwrap())
831-
.collect(),
832+
.collect::<Vec<_>>(),
832833
&self.sv[idx_2]
833834
.x
834835
.iter()
835836
.map(|e| e.to_f64().unwrap())
836-
.collect(),
837+
.collect::<Vec<_>>(),
837838
)
838839
.unwrap(),
839840
)),
@@ -888,18 +889,18 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
888889
self.sv[v1].alpha -= step.to_f64().unwrap();
889890
self.sv[v2].alpha += step.to_f64().unwrap();
890891

892+
let xi_v1: Vec<_> = self.sv[v1].x.iter().map(|e| e.to_f64().unwrap()).collect();
893+
let xi_v2: Vec<_> = self.sv[v2].x.iter().map(|e| e.to_f64().unwrap()).collect();
891894
for i in 0..self.sv.len() {
895+
let xj: Vec<_> = self.sv[i].x.iter().map(|e| e.to_f64().unwrap()).collect();
892896
let k2 = cache.get(
893897
&self.sv[v2],
894898
&self.sv[i],
895899
self.parameters
896900
.kernel
897901
.as_ref()
898902
.unwrap()
899-
.apply(
900-
&self.sv[v2].x.iter().map(|e| e.to_f64().unwrap()).collect(),
901-
&self.sv[i].x.iter().map(|e| e.to_f64().unwrap()).collect(),
902-
)
903+
.apply(&xi_v2, &xj)
903904
.unwrap(),
904905
);
905906
let k1 = cache.get(
@@ -909,10 +910,7 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>
909910
.kernel
910911
.as_ref()
911912
.unwrap()
912-
.apply(
913-
&self.sv[v1].x.iter().map(|e| e.to_f64().unwrap()).collect(),
914-
&self.sv[i].x.iter().map(|e| e.to_f64().unwrap()).collect(),
915-
)
913+
.apply(&xi_v1, &xj)
916914
.unwrap(),
917915
);
918916
self.sv[i].grad -= step.to_f64().unwrap() * (k2 - k1);

src/svm/svr.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -248,19 +248,20 @@ impl<'a, T: Number + FloatNumber + PartialOrd, X: Array2<T>, Y: Array1<T>> SVR<'
248248

249249
let mut y_hat: Vec<T> = Vec::<T>::zeros(n);
250250

251+
let mut x_i = Vec::with_capacity(n);
251252
for i in 0..n {
252-
y_hat.set(
253-
i,
254-
self.predict_for_row(Vec::from_iterator(x.get_row(i).iterator(0).copied(), n)),
255-
);
253+
x_i.clear();
254+
x_i.extend(x.get_row(i).iterator(0).copied());
255+
y_hat.set(i, self.predict_for_row(&x_i));
256256
}
257257

258258
Ok(y_hat)
259259
}
260260

261-
pub(crate) fn predict_for_row(&self, x: Vec<T>) -> T {
261+
pub(crate) fn predict_for_row(&self, x: &[T]) -> T {
262262
let mut f = self.b;
263263

264+
let xi: Vec<_> = x.iter().map(|e| e.to_f64().unwrap()).collect();
264265
for i in 0..self.instances.as_ref().unwrap().len() {
265266
f += self.w.as_ref().unwrap()[i]
266267
* T::from(
@@ -270,10 +271,7 @@ impl<'a, T: Number + FloatNumber + PartialOrd, X: Array2<T>, Y: Array1<T>> SVR<'
270271
.kernel
271272
.as_ref()
272273
.unwrap()
273-
.apply(
274-
&x.iter().map(|e| e.to_f64().unwrap()).collect(),
275-
&self.instances.as_ref().unwrap()[i],
276-
)
274+
.apply(&xi, &self.instances.as_ref().unwrap()[i])
277275
.unwrap(),
278276
)
279277
.unwrap()

0 commit comments

Comments
 (0)