Skip to content

Instantly share code, notes, and snippets.

@makoConstruct
Created January 28, 2020 06:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save makoConstruct/0c835eda538cd772fcf75bd61699a627 to your computer and use it in GitHub Desktop.
Save makoConstruct/0c835eda538cd772fcf75bd61699a627 to your computer and use it in GitHub Desktop.
a battery of tests for comparing different mathematical specifications of comparison aggregation
trait MetricaWire {
fn sign(&self)-> f32;
// fn controversy(&self)-> f32;
// fn certainty(&self)-> f32;
fn negate(&self)-> Self;
fn zero()-> Self;
fn unit()-> Self;
fn of_strength(v:f32)-> Self;
}
trait Metrica {
type Wire:MetricaWire;
fn serial(&self, a: &Self::Wire, b: &Self::Wire)-> Self::Wire;
fn parallel(&self, a: &Self::Wire, b: &Self::Wire)-> Self::Wire;
// fn triangle_to_y(&self, a: &Wire, b: &Wire, c: &Wire)-> (Wire, Wire, Wire); //anticlockwise
}
fn equalish(a:f32, b:f32)-> bool {
(a - b).abs() < 0.00001
}
// I can't fucking do this
// this was supposed to allow you to build wire reduction expressions by typing things like "p(p(1 1) s(1 p(2 2)))". But macros are too horrible to work for that.
// macro_rules! reduction_test {
// ($M:ty, $m:expr) => ();
// ($M:ty, $m:expr, u) => {
// &<$M>::Wire::unit()
// };
// ($M:ty, $m:expr, (p )) => ();
// ($M:ty, $m:expr, (p $first:tt )) => {
// reduction_test!($M, $m, $first)
// };
// ($M:ty, $m:expr, (p $first:tt, $($ir:tt),+ )) => {
// &$m.parallel(
// reduction_test!($M, $m, $first),
// reduction_test!($M, $m, (p $($ir),* ))
// )
// };
// ($M:ty, $m:expr, (p $($ir:tt),* ), $($rest:tt),*) => {
// reduction_test!($M, $m, (p $($ir),* ))
// reduction_test!($M, $m, $($rest),*)
// };
// ($M:ty, $m:expr, (s )) => ();
// ($M:ty, $m:expr, (s $first:tt )) => {
// reduction_test!($M, $m, $first)
// };
// ($M:ty, $m:expr, (s $first:tt, $($ir:tt),+ )) => {
// &$m.serial(
// reduction_test!($M, $m, $first),
// reduction_test!($M, $m, (s $($ir),* ))
// )
// };
// ($M:ty, $m:expr, (s $($ir:tt),* ), $($rest:tt),*) => {
// reduction_test!($M, $m, (s $($ir),* ))
// reduction_test!($M, $m, $($rest),*)
// };
// ($M:ty, $m:expr, $n:expr) => {
// &<$M>::Wire::of_strength($n as f32)
// };
// }
macro_rules! test {
{$name:expr, $handler:ident, $($test:expr,)*} => {
$(
if !($test) {
if $handler(format!("{}:{}", $name, stringify!($test))) {
return;
}
}
)*
};
}
fn test_metrica<M:Metrica, F:FnMut(String)-> bool>(m:&M, mut error_handler:F){
let nunit = M::Wire::unit();
let ndub = M::Wire::of_strength(2f32);
// a b
test!{
"single edge", error_handler,
m.serial(&nunit, &nunit).sign() > 0.0,
m.parallel(
&m.serial(&nunit, &nunit),
&m.serial(&nunit, &nunit),
).sign() > 0.0,
};
// a b
// b c
// c a
test!{
"tricycle", error_handler,
//comparing a c
equalish(m.parallel(&m.serial(&nunit, &nunit), &nunit.negate()).sign(), 0.0),
};
// a b
// c b
// d a
// d c
test!{
"forward square", error_handler,
// d < a
m.parallel(
&m.serial(&nunit, &nunit),
&m.serial(&nunit, &nunit),
).sign() > 0.0,
// a == c
equalish(m.parallel(
&m.serial(&nunit.negate(), &nunit),
&m.serial(&nunit, &nunit.negate()),
).sign(), 0.0),
// c < b
m.parallel(
&nunit,
&m.serial(&m.serial(&nunit.negate(), &nunit), &nunit),
).sign() > 0.0,
};
// a b
// b c
// c a 2
test!{
"tri strong return", error_handler,
// c < b
m.parallel(
&nunit.negate(),
&m.serial(&ndub, &nunit)
).sign() > 0.0,
// b < a
m.parallel(
&nunit.negate(),
&m.serial(&nunit, &ndub)
).sign() > 0.0,
};
// a b 2
// b c
// c d 2
// d a
test!{
"uneven cycle square", error_handler,
// a == c
equalish(m.parallel(
&m.serial(&ndub, &nunit),
&m.serial(&nunit.negate(), &ndub.negate()),
).sign(), 0.0),
// a < b
m.parallel(
&ndub,
&m.serial(&m.serial(&nunit.negate(), &ndub.negate()), &nunit.negate()),
).sign() > 0.0,
}
// a b c
// c e1
// c e2
// c e3
// c e4
test!{
"broom", error_handler,
equalish()
}
}
fn print_test_metrica<M:Metrica>(m:&M){
let counter = |v:String|-> bool {
println!("failure: {}", &v);
false
};
test_metrica(m, counter);
}
fn count_test_metrica<M:Metrica>(m:&M)-> usize {
let mut count = 0;
let counter = |_:String|-> bool {
count += 1;
false
};
test_metrica(m, counter);
count
}
fn strict_test_metrica<M:Metrica>(m:&M)-> bool {
let mut count = false;
let counter = |_:String|-> bool {
count = true;
true
};
test_metrica(m, counter);
count
}
struct DuWire {
up: f32,
down: f32,
}
struct DuMetric();
impl MetricaWire for DuWire {
fn sign(&self)-> f32 { self.up - self.down }
// fn controversy(&self)-> f32 { (self.up + self.down)/(self.up - self.down).abs() } //1 is minimum, infinite is maximum
// fn certainty(&self)-> f32 { log((self.up + self.down)/self.controversy()) }
fn negate(&self)-> Self { DuWire{ up:self.down, down:self.up } }
fn zero()-> Self { DuWire{ up:0.0, down:0.0 } }
fn unit()-> Self { DuWire{ up:1.0, down:0.0 } }
fn of_strength(v:f32)-> Self {
if v >= 0.0 {
DuWire{ up:v, down:0.0 }
}else{
DuWire{ up:0.0, down:-v }
}
}
}
impl Metrica for DuMetric {
type Wire = DuWire;
fn serial(&self, a: &Self::Wire, b: &Self::Wire)-> Self::Wire { DuWire{ up: a.up.min(b.up), down: a.down.min(b.down) } }
fn parallel(&self, a: &Self::Wire, b: &Self::Wire)-> Self::Wire { DuWire{ up: a.up + b.up, down: a.down + b.down } }
// fn triangle_to_y(&self, a: &Wire, b: &Wire, c: &Wire)-> (Wire, Wire, Wire) { } //anticlockwise
}
struct AvMetric();
impl Metrica for AvMetric {
type Wire = DuWire;
fn serial(&self, a: &Self::Wire, b: &Self::Wire)-> Self::Wire {
let ap = a.up + a.down;
let bp = b.up + b.down;
let tp = ap + bp;
DuWire{
up: (a.up*ap + b.up*bp)/tp,
down: (a.down*ap + b.down*bp)/tp,
}
}
fn parallel(&self, a: &Self::Wire, b: &Self::Wire)-> Self::Wire { DuWire{ up: a.up + b.up, down: a.down + b.down } }
// fn triangle_to_y(&self, a: &Wire, b: &Wire, c: &Wire)-> (Wire, Wire, Wire) { } //anticlockwise
}
fn main(){
print_test_metrica(&AvMetric());
// let m = DuMetric();
// let nunit = <DuMetric as Metrica>::Wire::unit();
// println!("{}", m.parallel(&m.serial(&nunit, &nunit), &nunit.negate()).sign());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment