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