[lab2] Structs hierarchy refactoring
This commit is contained in:
parent
837dfe9ba0
commit
f4f8f43d3e
@ -2,10 +2,15 @@ use super::BitVector;
|
||||
use super::operations::attentivenessCheck;
|
||||
use super::operations::similarityCheck;
|
||||
|
||||
pub struct AdaptiveResonanceTheoryConfig {
|
||||
pub beta: usize,
|
||||
pub attentiveness: f64,
|
||||
}
|
||||
|
||||
|
||||
pub fn adaptiveResonanceTheoryImpl(
|
||||
data: &[BitVector],
|
||||
beta: usize,
|
||||
attentiveness: f64,
|
||||
cfg: &AdaptiveResonanceTheoryConfig
|
||||
) -> Box<[usize]> {
|
||||
let mut prototypes = Vec::<BitVector>::new();
|
||||
let mut groups = vec![0usize; data.len()].into_boxed_slice();
|
||||
@ -17,10 +22,10 @@ pub fn adaptiveResonanceTheoryImpl(
|
||||
|
||||
'elements: for i in 1..data.len() {
|
||||
for j in 0..prototypes.len() {
|
||||
if !similarityCheck(&prototypes[j], &data[i], beta) {
|
||||
if !similarityCheck(&prototypes[j], &data[i], cfg.beta) {
|
||||
continue;
|
||||
}
|
||||
if !attentivenessCheck(&prototypes[j], &data[i], attentiveness) {
|
||||
if !attentivenessCheck(&prototypes[j], &data[i], cfg.attentiveness) {
|
||||
continue;
|
||||
}
|
||||
groups[i] = j;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
mod bit_vector;
|
||||
mod operations;
|
||||
mod r#impl;
|
||||
mod operations;
|
||||
|
||||
pub use bit_vector::BitVector;
|
||||
pub use r#impl::adaptiveResonanceTheoryImpl;
|
||||
pub use r#impl::{AdaptiveResonanceTheoryConfig, adaptiveResonanceTheoryImpl};
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
use crate::algo::BitVector;
|
||||
use crate::algo::{AdaptiveResonanceTheoryConfig, BitVector};
|
||||
use bgtu_ai_utility::{UpdatePending, UpdateTarget};
|
||||
use std::ops::{Index, IndexMut};
|
||||
|
||||
pub(crate) struct MyApp {
|
||||
pub _isFirstFrame: bool,
|
||||
pub bitCount: usize,
|
||||
pub beta: usize,
|
||||
pub attentiveness: f64,
|
||||
pub data: Vec<BitVector>,
|
||||
pub config: AdaptiveResonanceTheoryConfig,
|
||||
pub data: VectorsList,
|
||||
pub result: Option<Box<[usize]>>,
|
||||
pub columnUpdate: UpdatePending,
|
||||
pub rowUpdate: UpdatePending,
|
||||
@ -15,24 +13,75 @@ pub(crate) struct MyApp {
|
||||
impl MyApp {
|
||||
pub(crate) fn new() -> Self {
|
||||
return Self {
|
||||
_isFirstFrame: true,
|
||||
bitCount: 0,
|
||||
beta: 1,
|
||||
attentiveness: 0.5,
|
||||
data: Vec::new(),
|
||||
config: AdaptiveResonanceTheoryConfig {
|
||||
beta: 1,
|
||||
attentiveness: 0.5,
|
||||
},
|
||||
data: VectorsList::new(),
|
||||
result: None,
|
||||
columnUpdate: UpdatePending::NoChange,
|
||||
rowUpdate: UpdatePending::NoChange,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VectorsList {
|
||||
bitCount: usize,
|
||||
data: Vec<BitVector>,
|
||||
}
|
||||
|
||||
impl VectorsList {
|
||||
pub fn new() -> Self {
|
||||
return Self {
|
||||
bitCount: 0,
|
||||
data: Vec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn update_columns<'s>(&'s mut self) -> ColumnsUpdateTarget<'s> {
|
||||
return ColumnsUpdateTarget { data: self };
|
||||
}
|
||||
|
||||
pub fn bit_count(&self) -> usize {
|
||||
return self.bitCount;
|
||||
}
|
||||
|
||||
pub fn as_slice<'s>(&'s self) -> &'s [BitVector] {
|
||||
return self.data.as_slice();
|
||||
}
|
||||
pub fn len<'s>(&self) -> usize {
|
||||
return self.data.len();
|
||||
}
|
||||
}
|
||||
|
||||
struct ColumnsUpdateTarget<'d> {
|
||||
data: &'d mut MyApp,
|
||||
impl Index<usize> for VectorsList {
|
||||
type Output = BitVector;
|
||||
|
||||
fn index(&self, i: usize) -> &Self::Output {
|
||||
return self.data.index(i);
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<usize> for VectorsList {
|
||||
fn index_mut(&mut self, i: usize) -> &mut Self::Output {
|
||||
return self.data.index_mut(i);
|
||||
}
|
||||
}
|
||||
|
||||
impl UpdateTarget for VectorsList {
|
||||
type Elem = ();
|
||||
|
||||
fn add(&mut self, value: Self::Elem) {
|
||||
UpdateTarget::add(&mut self.data, BitVector::alloc(self.bitCount));
|
||||
}
|
||||
|
||||
fn remove(&mut self, index: usize) {
|
||||
UpdateTarget::remove(&mut self.data, index);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ColumnsUpdateTarget<'d> {
|
||||
data: &'d mut VectorsList,
|
||||
}
|
||||
|
||||
impl UpdateTarget for ColumnsUpdateTarget<'_> {
|
||||
|
||||
@ -7,12 +7,12 @@ use egui_extras::{Column, TableBuilder};
|
||||
|
||||
pub(crate) fn input(ui: &mut Ui, data: &mut MyApp) {
|
||||
ui.add_enabled_ui(matches!(data.result, None), |ui| {
|
||||
labeled_slider(ui, "beta", &mut data.beta, 1..=10, 1f64);
|
||||
labeled_slider(ui, "beta", &mut data.config.beta, 1..=10, 1f64);
|
||||
ui.label("");
|
||||
labeled_slider(
|
||||
ui,
|
||||
"attentiveness",
|
||||
&mut data.attentiveness,
|
||||
&mut data.config.attentiveness,
|
||||
0f64..=1f64,
|
||||
0.001,
|
||||
);
|
||||
@ -34,8 +34,7 @@ pub(crate) fn input(ui: &mut Ui, data: &mut MyApp) {
|
||||
if ui.button("Classify").clicked() {
|
||||
data.result = Some(algo::adaptiveResonanceTheoryImpl(
|
||||
data.data.as_slice(),
|
||||
data.beta,
|
||||
data.attentiveness,
|
||||
&data.config,
|
||||
))
|
||||
}
|
||||
});
|
||||
@ -48,7 +47,7 @@ pub(crate) fn input(ui: &mut Ui, data: &mut MyApp) {
|
||||
});
|
||||
|
||||
ui.label("");
|
||||
|
||||
|
||||
table(ui, data);
|
||||
}
|
||||
|
||||
@ -58,7 +57,7 @@ fn table(ui: &mut Ui, data: &mut MyApp) {
|
||||
.resizable(true)
|
||||
.column(Column::remainder())
|
||||
.column(Column::remainder())
|
||||
.columns(Column::remainder(), data.bitCount)
|
||||
.columns(Column::remainder(), data.data.bit_count())
|
||||
.header(20.0, |mut header| {
|
||||
header.col(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
@ -68,7 +67,7 @@ fn table(ui: &mut Ui, data: &mut MyApp) {
|
||||
header.col(|ui| {
|
||||
ui.label("Group");
|
||||
});
|
||||
for i in 0..data.bitCount {
|
||||
for i in 0..data.data.bit_count() {
|
||||
header.col(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(i.to_string());
|
||||
@ -86,9 +85,11 @@ fn table(ui: &mut Ui, data: &mut MyApp) {
|
||||
let i = row.index();
|
||||
row.col(|ui| {
|
||||
ui.horizontal(|ui| {
|
||||
if ui.button("-").clicked() {
|
||||
data.rowUpdate = UpdatePending::Remove(i);
|
||||
}
|
||||
ui.add_enabled_ui(matches!(data.result, None), |ui| {
|
||||
if ui.button("-").clicked() {
|
||||
data.rowUpdate = UpdatePending::Remove(i);
|
||||
}
|
||||
});
|
||||
ui.label(i.to_string());
|
||||
});
|
||||
});
|
||||
@ -99,7 +100,7 @@ fn table(ui: &mut Ui, data: &mut MyApp) {
|
||||
ui.label("?");
|
||||
}
|
||||
});
|
||||
for j in 0..data.bitCount {
|
||||
for j in 0..data.data.bit_count() {
|
||||
row.col(|ui| {
|
||||
ui.add_enabled_ui(matches!(data.result, None), |ui| {
|
||||
ui.checkbox(&mut data.data[i][j], "");
|
||||
|
||||
@ -11,18 +11,16 @@ fn main() -> eframe::Result {
|
||||
return boot_eframe(|| gui::MyApp::new());
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl eframe::App for gui::MyApp {
|
||||
fn update(&mut self, ui: &eframe::egui::Context, _frame: &mut eframe::Frame) {
|
||||
self.columnUpdate.apply(
|
||||
&mut self.update_columns(),
|
||||
self.columnUpdate.apply_and_clear(
|
||||
&mut self.data.update_columns(),
|
||||
|| false
|
||||
);
|
||||
|
||||
self.rowUpdate.apply_and_clear(
|
||||
&mut self.data,
|
||||
|| BitVector::alloc(self.bitCount)
|
||||
|| ()
|
||||
);
|
||||
|
||||
egui::CentralPanel::default().show(ui, |ui| {
|
||||
|
||||
@ -25,24 +25,6 @@ impl UpdatePending {
|
||||
}
|
||||
*self = UpdatePending::NoChange;
|
||||
}
|
||||
|
||||
pub fn apply_many<'c, C: UpdateTarget + 'c>(
|
||||
&self,
|
||||
it: impl Iterator<Item = &'c mut C>,
|
||||
constructor: impl Fn() -> C::Elem,
|
||||
) {
|
||||
for e in it {
|
||||
self.apply(e, || constructor())
|
||||
}
|
||||
}
|
||||
pub fn apply_many_and_clear<'c, C: UpdateTarget + 'c>(
|
||||
&mut self,
|
||||
it: impl Iterator<Item = &'c mut C>,
|
||||
constructor: impl Fn() -> C::Elem,
|
||||
) {
|
||||
self.apply_many(it, constructor);
|
||||
*self = UpdatePending::NoChange;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait UpdateTarget {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user