Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions math_explorer_gui/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::tabs::{
ai::AiTab, battery_degradation::BatteryDegradationTab, chaos::ChaosTab,
clinical_trials::ClinicalTrialsTab, epidemiology::EpidemiologyTab, favoritism::FavoritismTab,
fluid_dynamics::FluidDynamicsTab, game_theory::GameTheoryTab, medical::MedicalTab,
morphogenesis::MorphogenesisTab, mri::MriTab, neuroscience::NeuroscienceTab,
number_theory::NumberTheoryTab, quantum::QuantumTab, solid_state::SolidStateTab, ExplorerTab,
financial_math::FinancialMathTab, fluid_dynamics::FluidDynamicsTab, game_theory::GameTheoryTab,
medical::MedicalTab, morphogenesis::MorphogenesisTab, mri::MriTab,
neuroscience::NeuroscienceTab, number_theory::NumberTheoryTab, quantum::QuantumTab,
solid_state::SolidStateTab, ExplorerTab,
};
use eframe::egui;

Expand Down Expand Up @@ -31,6 +32,7 @@ impl Default for MathExplorerApp {
Box::new(BatteryDegradationTab::default()),
Box::new(AiTab::default()),
Box::new(FavoritismTab::default()),
Box::new(FinancialMathTab::default()),
],
selected_tab: 0,
}
Expand Down
31 changes: 18 additions & 13 deletions math_explorer_gui/src/tabs/ai/attention_maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ impl Default for AttentionMapsTool {

impl AttentionMapsTool {
fn recalculate(&mut self) {
let (output, weights) = math_explorer::ai::transformer::attention::scaled_dot_product_attention(
&self.q_matrix,
&self.k_matrix,
&self.v_matrix,
None,
);
let (output, weights) =
math_explorer::ai::transformer::attention::scaled_dot_product_attention(
&self.q_matrix,
&self.k_matrix,
&self.v_matrix,
None,
);
self.output_matrix = output;
self.attention_weights = weights;
}
Expand Down Expand Up @@ -93,10 +94,8 @@ impl AttentionMapsTool {
((1.0 - normalized) * 200.0 + 55.0) as u8,
);

let (rect, _response) = ui.allocate_exact_size(
egui::vec2(40.0, 40.0),
egui::Sense::hover(),
);
let (rect, _response) =
ui.allocate_exact_size(egui::vec2(40.0, 40.0), egui::Sense::hover());

ui.painter().rect_filled(rect, 2.0, color);

Expand Down Expand Up @@ -135,13 +134,15 @@ impl AiTool for AttentionMapsTool {
ui.vertical(|ui| {
let mut changed = false;
ui.group(|ui| {
changed |= Self::draw_matrix_input(ui, "Queries (Q)", &mut self.q_matrix);
changed |=
Self::draw_matrix_input(ui, "Queries (Q)", &mut self.q_matrix);
});
ui.group(|ui| {
changed |= Self::draw_matrix_input(ui, "Keys (K)", &mut self.k_matrix);
});
ui.group(|ui| {
changed |= Self::draw_matrix_input(ui, "Values (V)", &mut self.v_matrix);
changed |=
Self::draw_matrix_input(ui, "Values (V)", &mut self.v_matrix);
});

if changed {
Expand All @@ -153,7 +154,11 @@ impl AiTool for AttentionMapsTool {

ui.vertical(|ui| {
ui.group(|ui| {
Self::draw_heatmap(ui, "Attention Weights (softmax(Q * K^T / sqrt(d_k)))", &self.attention_weights);
Self::draw_heatmap(
ui,
"Attention Weights (softmax(Q * K^T / sqrt(d_k)))",
&self.attention_weights,
);
});

ui.add_space(20.0);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use super::BatteryDegradationTool;
use eframe::egui;
use math_explorer::applied::battery_degradation::{
Capacity, DepthOfDischarge, PowerLawModel,
};
use math_explorer::applied::battery_degradation::{Capacity, DepthOfDischarge, PowerLawModel};

pub struct LifetimeEstimatorTool {
target_capacity: f64,
Expand Down
181 changes: 181 additions & 0 deletions math_explorer_gui/src/tabs/financial_math/bankroll_growth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
use super::FinancialMathTool;
use eframe::egui;
use egui_plot::{Line, Plot, PlotPoints};
use math_explorer::pure_math::statistics::kelly::{
kelly_fraction, variants, BankrollFraction, EdgeProbability, Odds,
};
use rand::Rng;

pub struct BankrollGrowthTool {
initial_bankroll: f64,
probability: f64,
odds: f64,
num_bets: usize,

// Cached plot data
full_kelly_points: Vec<[f64; 2]>,
half_kelly_points: Vec<[f64; 2]>,
quarter_kelly_points: Vec<[f64; 2]>,

error_msg: Option<String>,
}

impl Default for BankrollGrowthTool {
fn default() -> Self {
let mut tool = Self {
initial_bankroll: 1000.0,
probability: 0.55,
odds: 2.0, // Decimal odds (net profit multiplier + 1, wait Kelly odds b is net profit multiplier. The Odds type in math_explorer: Odds::new(b). Let's check.)
num_bets: 100,
full_kelly_points: vec![],
half_kelly_points: vec![],
quarter_kelly_points: vec![],
error_msg: None,
};
tool.recalculate();
tool
}
}

impl BankrollGrowthTool {
fn recalculate(&mut self) {
self.full_kelly_points.clear();
self.half_kelly_points.clear();
self.quarter_kelly_points.clear();
self.error_msg = None;

let prob_result = EdgeProbability::new(self.probability);
let odds_result = Odds::new(self.odds);

match (prob_result, odds_result) {
(Ok(p), Ok(o)) => {
let full_kelly_res = kelly_fraction(&p, &o);
let half_kelly_res = variants::half_kelly(&p, &o);
let quarter_kelly_res = variants::quarter_kelly(&p, &o);

match (full_kelly_res, half_kelly_res, quarter_kelly_res) {
(Ok(fk), Ok(hk), Ok(qk)) => {
let mut rng = rand::thread_rng();

let mut fk_bankroll = self.initial_bankroll;
let mut hk_bankroll = self.initial_bankroll;
let mut qk_bankroll = self.initial_bankroll;

self.full_kelly_points.push([0.0, fk_bankroll]);
self.half_kelly_points.push([0.0, hk_bankroll]);
self.quarter_kelly_points.push([0.0, qk_bankroll]);

for i in 1..=self.num_bets {
let win = rng.r#gen::<f64>() < p.value();

// Let's create a helper closure for bankroll update
let update_bankroll =
|bankroll: &mut f64, fraction: &BankrollFraction| {
let bet_amount = *bankroll * fraction.value();
if win {
*bankroll += bet_amount * o.value();
} else {
*bankroll -= bet_amount;
}
};

update_bankroll(&mut fk_bankroll, &fk);
update_bankroll(&mut hk_bankroll, &hk);
update_bankroll(&mut qk_bankroll, &qk);

self.full_kelly_points.push([i as f64, fk_bankroll]);
self.half_kelly_points.push([i as f64, hk_bankroll]);
self.quarter_kelly_points.push([i as f64, qk_bankroll]);
}
}
(Err(e), _, _) | (_, Err(e), _) | (_, _, Err(e)) => {
self.error_msg = Some(format!("Error: {:?}", e)); // e is an enum
}
}
}
(Err(e), _) => {
self.error_msg = Some(format!("Error: {:?}", e));
}
(_, Err(e)) => {
self.error_msg = Some(format!("Error: {:?}", e));
Comment on lines +92 to +100
}
}
}
}

impl FinancialMathTool for BankrollGrowthTool {
fn name(&self) -> &'static str {
"Bankroll Growth"
}

fn show(&mut self, ui: &mut egui::Ui) {
ui.vertical(|ui| {
ui.heading("Parameters");
let mut changed = false;

changed |= ui
.add(
egui::Slider::new(&mut self.initial_bankroll, 100.0..=10000.0)
.text("Initial Bankroll"),
)
.changed();
changed |= ui
.add(
egui::Slider::new(&mut self.probability, 0.01..=0.99)
.text("Win Probability (p)"),
)
.changed();
changed |= ui
.add(egui::Slider::new(&mut self.odds, 0.1..=10.0).text("Net Odds (b)"))
.on_hover_text("Net profit multiplier. E.g., for +100 / even money, b = 1.0.")
Comment on lines +129 to +130
.changed();
changed |= ui
.add(egui::Slider::new(&mut self.num_bets, 10..=1000).text("Number of Bets"))
.changed();

if ui.button("Rerun Simulation").clicked() {
changed = true;
}

if changed {
self.recalculate();
}

ui.separator();

if let Some(ref err) = self.error_msg {
ui.colored_label(egui::Color32::RED, err);
} else {
ui.heading("Bankroll Simulation");

let plot = Plot::new("bankroll_growth_plot")
.view_aspect(2.0)
.legend(egui_plot::Legend::default());

plot.show(ui, |plot_ui| {
plot_ui.line(
Line::new(
"Full Kelly",
PlotPoints::new(self.full_kelly_points.clone()),
)
.color(egui::Color32::RED),
);
plot_ui.line(
Line::new(
"Half Kelly",
PlotPoints::new(self.half_kelly_points.clone()),
)
.color(egui::Color32::YELLOW),
);
plot_ui.line(
Line::new(
"Quarter Kelly",
PlotPoints::new(self.quarter_kelly_points.clone()),
)
.color(egui::Color32::GREEN),
);
});
}
});
}
}
58 changes: 58 additions & 0 deletions math_explorer_gui/src/tabs/financial_math/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crate::tabs::ExplorerTab;
use eframe::egui;

pub mod bankroll_growth;

/// A trait for sub-tools within the Financial Math tab.
pub trait FinancialMathTool {
/// Returns the name of the tool.
fn name(&self) -> &'static str;

/// Renders the tool's UI.
fn show(&mut self, ui: &mut egui::Ui);
}
Comment on lines +6 to +13

pub struct FinancialMathTab {
tools: Vec<Box<dyn FinancialMathTool>>,
selected_tool_index: usize,
}

impl Default for FinancialMathTab {
fn default() -> Self {
Self {
tools: vec![Box::new(bankroll_growth::BankrollGrowthTool::default())],
selected_tool_index: 0,
}
}
}

impl ExplorerTab for FinancialMathTab {
fn name(&self) -> &'static str {
"Financial Math"
}

fn show(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::SidePanel::left("financial_math_tool_selector").show(ctx, |ui| {
ui.heading("Tools");
ui.separator();
for (i, tool) in self.tools.iter().enumerate() {
if ui
.selectable_label(self.selected_tool_index == i, tool.name())
.clicked()
{
self.selected_tool_index = i;
}
}
});

egui::CentralPanel::default().show(ctx, |ui| {
if let Some(tool) = self.tools.get_mut(self.selected_tool_index) {
tool.show(ui);
} else {
ui.centered_and_justified(|ui| {
ui.label("No tool selected");
});
}
});
}
}
1 change: 1 addition & 0 deletions math_explorer_gui/src/tabs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod chaos;
pub mod clinical_trials;
pub mod epidemiology;
pub mod favoritism;
pub mod financial_math;
pub mod fluid_dynamics;
pub mod game_theory;
pub mod medical;
Expand Down
2 changes: 1 addition & 1 deletion todo_gui.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ This document outlines the roadmap for integrating the various modules of the `m
### 4.4 Financial Math (Kelly Criterion)
* **Module:** `pure_math::statistics::kelly`
* **Features:**
* [ ] **Bankroll Growth:** Simulation of wealth over multiple bets using Kelly vs. fractional Kelly.
* [x] **Bankroll Growth:** Simulation of wealth over multiple bets using Kelly vs. fractional Kelly.
* [ ] **Bet Size Calculator:** Input fields for odds and probability of winning.

---
Expand Down
Loading