use arael::model::{Param, Model};
use arael::vect::vect3f;
use arael::matrix::matrix3f;
use arael::info;
#[arael::model]
struct DataEntry {
x: f32,
y: f32,
}
#[arael::model]
#[arael(skip_self_block)]
struct LinearModel {
a: Param<f32>,
b: Param<f32>,
data: Vec<DataEntry>,
}
fn main() {
info!("=== LinearModel: serialize / update / deserialize ===");
info!("");
let mut model = LinearModel {
a: Param::new(1.0),
b: Param::new(0.0),
data: vec![
DataEntry { x: 1.0, y: 2.1 },
DataEntry { x: 2.0, y: 3.9 },
DataEntry { x: 3.0, y: 6.1 },
],
};
let mut params = Vec::new();
model.serialize_params32(&mut params);
info!("Serialized params: {:?}", params); info!(" a index={}, b index={}", model.a.value, model.b.value);
model.update_self();
info!("");
info!("After update_self:");
info!(" a.work={}, b.work={}", model.a.work(), model.b.work());
params[0] = 2.0; params[1] = 0.1; info!("");
info!("Optimizer sets params to: {:?}", params);
model.update32(¶ms);
info!("After update:");
info!(" a.work={}, b.work={}", model.a.work(), model.b.work());
info!(" a.value={}, b.value={} (unchanged)", model.a.value, model.b.value);
let cost: f32 = model.data.iter().map(|d| {
let predicted = model.a.work() * d.x + model.b.work();
let residual = d.y - predicted;
residual * residual
}).sum();
info!(" Cost = {:.4}", cost);
model.deserialize_params32(¶ms);
info!("");
info!("After deserialize (commit):");
info!(" a.value={}, b.value={}", model.a.value, model.b.value);
info!("");
info!("=== Fixed parameter demo ===");
info!("");
let mut model2 = LinearModel {
a: Param::fixed(2.0), b: Param::new(0.0), data: vec![DataEntry { x: 1.0, y: 2.0 }],
};
let mut params2 = Vec::new();
model2.serialize_params32(&mut params2);
info!("With a=fixed(2.0), b=new(0.0):");
info!(" Serialized params: {:?} (only b)", params2);
params2[0] = 0.5;
model2.update32(¶ms2);
info!(" After update: a.work={}, b.work={}", model2.a.work(), model2.b.work());
info!("");
info!("=== Computed field (rotation from euler angles) ===");
info!("");
#[arael::model]
#[arael(skip_self_block)]
struct Pose {
pos: Param<vect3f>,
ea: Param<vect3f>,
#[arael(compute = ea.rotation_matrix())]
mr2w: matrix3f,
}
let mut pose = Pose {
pos: Param::new(vect3f::new(1.0, 2.0, 3.0)),
ea: Param::new(vect3f::new(0.0, 0.0, std::f32::consts::FRAC_PI_2)),
mr2w: matrix3f::identity(),
};
let mut params3 = Vec::new();
pose.serialize_params32(&mut params3);
info!("Pose params: {:?}", params3); info!(" {} params total (pos=3 + ea=3)", params3.len());
pose.update_self();
info!("");
info!("After update_self, mr2w computed from euler angles:");
info!(" mr2w = {:?}", pose.mr2w);
params3[5] = 0.0; pose.update32(¶ms3);
info!("");
info!("After update with ea.z=0:");
info!(" ea.work = {:?}", pose.ea.work());
info!(" mr2w = {:?} (should be ~identity)", pose.mr2w);
}