use geoit::algebra::mv::Mv;
use geoit::algebra::ops;
use geoit::algebra::signature::Signature;
use geoit::governance::field::FieldOp;
use geoit::governance::geom_class::{inner_product_poly, norm_poly};
use geoit::governance::{govern, Construction, Expr, GeomClass, Governance, Phase, VariableMap};
use geoit::scalar::{Rat, Scalar};
fn cga3_governance() -> Governance {
let sig = Signature::new(1, 0, 4).unwrap();
let grade_mask = 0b10u64;
let e_origin = Mv::from_rat_terms(&[(0b00001, Rat::new(1, 2)), (0b00010, Rat::new(1, 2))]);
let e_infinity = Mv::from_rat_terms(&[(0b00001, Rat::from(-1)), (0b00010, Rat::from(1))]);
let derived_gens = vec![e_origin, e_infinity.clone()];
let var_map = VariableMap::for_grade_mask(&sig, grade_mask);
let null_eq = norm_poly(&sig, grade_mask, var_map.num_vars, &var_map.mask_to_var);
let ip_eq = inner_product_poly(
&e_infinity,
&sig,
grade_mask,
Rat::ONE,
var_map.num_vars,
&var_map.mask_to_var,
);
let point_class = GeomClass {
grade_mask,
equations: vec![null_eq, ip_eq],
inequalities: vec![],
field_op: FieldOp::default(),
expected_profile: None,
};
let euclidean = Expr::Add(
Expr::add(
Expr::mul(Expr::param(0), Expr::gen(2)),
Expr::mul(Expr::param(1), Expr::gen(3)),
),
Expr::mul(Expr::param(2), Expr::gen(4)),
);
let r_squared = Expr::Add(
Expr::add(
Expr::mul(Expr::param(0), Expr::param(0)),
Expr::mul(Expr::param(1), Expr::param(1)),
),
Expr::mul(Expr::param(2), Expr::param(2)),
);
let neg_half_r_sq = Expr::mul(
Box::new(Expr::Literal(Scalar::Rat(Rat::new(-1, 2)))),
Box::new(r_squared),
);
let conformal = Expr::Mul(neg_half_r_sq, Expr::dgen(1));
let body = Expr::Add(
Box::new(Expr::Add(Box::new(euclidean), Box::new(conformal))),
Expr::dgen(0),
);
Governance {
sig,
derived_gens,
geom_classes: vec![point_class],
constructions: vec![Construction {
class_index: 0,
arity: 3,
body,
}],
probe: None,
transform_rules: vec![],
}
}
#[test]
fn cga_derived_gen_properties() {
let gov = cga3_governance();
let eo = &gov.derived_gens[0];
let einf = &gov.derived_gens[1];
assert!(ops::norm_squared(eo, &gov.sig).is_zero());
assert!(ops::norm_squared(einf, &gov.sig).is_zero());
assert_eq!(
ops::scalar_product_value(eo, einf, &gov.sig),
Scalar::from(1i64)
);
}
#[test]
fn cga_point_is_null() {
let gov = cga3_governance();
let mv = gov
.construct(
0,
&[Scalar::from(3i64), Scalar::from(4i64), Scalar::from(5i64)],
)
.unwrap();
assert!(ops::norm_squared(&mv, &gov.sig).is_zero());
}
#[test]
fn cga_circuit_closes() {
let gov = cga3_governance();
let params = vec![Scalar::from(3i64), Scalar::from(4i64), Scalar::from(5i64)];
let mv = gov.construct(0, ¶ms).unwrap();
let geoit = govern(&mv, &gov, 0).unwrap();
assert!(geoit.is_satisfied());
assert_eq!(geoit.phase(), Phase::Evaluation);
assert_eq!(geoit.read_all().unwrap(), params);
}
#[test]
fn cga_circuit_origin() {
let gov = cga3_governance();
let params = vec![Scalar::from(0i64), Scalar::from(0i64), Scalar::from(0i64)];
let mv = gov.construct(0, ¶ms).unwrap();
let geoit = govern(&mv, &gov, 0).unwrap();
assert_eq!(geoit.read_all().unwrap(), params);
}
#[test]
fn cga_circuit_unit_points() {
let gov = cga3_governance();
for case in &[
vec![1, 0, 0],
vec![0, 1, 0],
vec![0, 0, 1],
vec![-1, 0, 0],
vec![1, 1, 1],
] {
let params: Vec<Scalar> = case.iter().map(|&n| Scalar::from(n as i64)).collect();
let mv = gov.construct(0, ¶ms).unwrap();
let geoit = govern(&mv, &gov, 0).unwrap();
assert_eq!(
geoit.read_all().unwrap(),
params,
"CGA failed for {:?}",
case
);
}
}
#[test]
fn cga_circuit_rational() {
let gov = cga3_governance();
let params = vec![
Scalar::Rat(Rat::new(1, 2)),
Scalar::Rat(Rat::new(1, 3)),
Scalar::Rat(Rat::new(1, 7)),
];
let mv = gov.construct(0, ¶ms).unwrap();
let geoit = govern(&mv, &gov, 0).unwrap();
assert_eq!(geoit.read_all().unwrap(), params);
}
#[test]
fn cga_point_construction() {
let gov = cga3_governance();
let mv = gov
.construct(
0,
&[Scalar::from(3i64), Scalar::from(4i64), Scalar::from(5i64)],
)
.unwrap();
assert_eq!(mv.coefficient(0b00001), Scalar::Rat(Rat::new(51, 2)));
assert_eq!(mv.coefficient(0b00010), Scalar::Rat(Rat::new(-49, 2)));
assert_eq!(mv.coefficient(0b00100), Scalar::from(3i64));
}
#[test]
fn cga_point_normalization() {
let gov = cga3_governance();
let mv = gov
.construct(
0,
&[Scalar::from(3i64), Scalar::from(4i64), Scalar::from(5i64)],
)
.unwrap();
let ip = ops::scalar_product_value(&mv, &gov.derived_gens[1], &gov.sig);
assert_eq!(ip, Scalar::from(1i64));
}
#[test]
fn cga_non_point_rejected() {
let gov = cga3_governance();
let mv = Mv::from_rat_terms(&[(0b00100, Rat::from(1))]);
assert!(govern(&mv, &gov, 0).is_err());
}