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
use num_traits::{Float, Zero, One};
use crate::solver::{Cone, LinAlg, SliceLike};
use crate::ConeSOC;
pub struct ConeRotSOC<L: LinAlg>
{
soc: ConeSOC<L>,
}
impl<L: LinAlg> ConeRotSOC<L>
{
pub fn new() -> Self
{
ConeRotSOC {
soc: ConeSOC::new(),
}
}
}
impl<L: LinAlg> Cone<L> for ConeRotSOC<L>
{
fn proj(&mut self, dual_cone: bool, x: &mut L::Sl) -> Result<(), ()>
{
let f0 = L::F::zero();
let f1 = L::F::one();
let f2 = f1 + f1;
let fsqrt2 = f2.sqrt();
if x.len() > 0 {
if x.len() == 1 {
let r = x.get(0);
x.set(0, r.max(f0));
}
else {
let r = x.get(0);
let s = x.get(1);
x.set(0, (r + s) / fsqrt2);
x.set(1, (r - s) / fsqrt2);
self.soc.proj(dual_cone, x)?;
let r = x.get(0);
let s = x.get(1);
x.set(0, (r + s) / fsqrt2);
x.set(1, (r - s) / fsqrt2);
}
}
Ok(())
}
fn product_group<G: Fn(&mut L::Sl) + Copy>(&self, dp_tau: &mut L::Sl, group: G)
{
group(dp_tau);
}
}