Make several changes, most notably make the reparametrizations optional, both in code and UI

This commit is contained in:
Jan Bergen 2024-05-23 17:30:01 +02:00
parent 6c54c16f87
commit 521113cd7c
4 changed files with 249 additions and 119 deletions

9
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,9 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
]
}

View File

@ -1,5 +1,7 @@
use core::f64::consts::PI;
use std::time::Instant;
use gauss_quad::GaussLegendre;
use num::Float;
use std::collections::HashMap;
use std::io;
use std::rc::Rc;
@ -138,7 +140,7 @@ pub fn omnes_integrand_tan(cache:&mut Cache, s_tick:f64, s:f64) -> Complex {
)
}
pub fn omnes_integrand(cache:&mut Cache, s_tick:f64, s:f64) -> Complex {
pub fn omnes_integrand_notan(cache:&mut Cache, s_tick:f64, s:f64) -> Complex {
(delta_with_lut(cache, s_tick) - delta_with_lut(cache, s))
/ (s_tick * (s_tick - s + Complex::new(0.0, EPSILON)))
}
@ -178,24 +180,58 @@ pub fn omnes(cache:&mut Cache, s:f64, n:u32, use_tan: bool) -> Complex {
let intgrl = if use_tan {
integrate_complex(&roots, &weights, S0.atan(), PI / 2.0, |s_tick| omnes_integrand_tan(cache, s_tick, s))
} else {
integrate_complex(&roots, &weights, S0, INF, |s_tick| omnes_integrand(cache, s_tick, s))
integrate_complex(&roots, &weights, S0, INF, |s_tick| omnes_integrand_notan(cache, s_tick, s))
};
let omnes_res = (s/PI*(intgrl)).exp() * (S0 / Complex::new(S0 - s, -EPSILON)).powf(delta_with_lut(cache, s) / PI);
//cache.omnes_lut.get_mut(&n).unwrap().insert(s.to_bits(), omnes_res);
println!("{:?}", omnes_res);
cache.omnes_lut.get_mut(&n).unwrap().insert(s.to_bits(), omnes_res);
omnes_res
}
pub fn phi0_integrand(cache:&mut Cache, x: f64, s: f64, n_omnes:u32, use_tan_omnes: bool) -> f64 {
let x_sub = x.tan().powi(2) + S0;
pub fn phi0_integrand_tan_xsub(cache:&mut Cache, s_tick: f64, s: f64, n_omnes:u32, use_tan_omnes: bool) -> f64 {
let x_sub = s_tick.tan().powi(2) + S0;
let omnes_s = omnes(cache, s, n_omnes, use_tan_omnes);
let omnes_x = omnes(cache, x_sub, n_omnes, use_tan_omnes);
(omnes_x / omnes_s).norm_sqr().ln()
/ ( (x_sub)* (x_sub-s) )
/ x.cos().powi(2) // Don't use x_sub here, since this term is from tan substitution itself
/ s_tick.cos().powi(2) // Don't use x_sub here, since this term is from tan substitution itself
}
pub fn phi0_integrand_notan_xsub(cache:&mut Cache, s_tick: f64, s: f64, n_omnes:u32, use_tan_omnes: bool) -> f64 {
let x_sub = s_tick.powi(2) + S0;
let omnes_s = omnes(cache, s, n_omnes, use_tan_omnes);
let omnes_x = omnes(cache, x_sub, n_omnes, use_tan_omnes);
(omnes_x / omnes_s).norm_sqr().ln()
/ ( (x_sub)* (x_sub-s) )
}
pub fn phi0_integrand_tan_noxsub(cache:&mut Cache, s_tick: f64, s: f64, n_omnes:u32, use_tan_omnes: bool) -> f64 {
let tansub = s_tick.tan();
println!("lol {:?}", omnes(cache, tansub, n_omnes, use_tan_omnes));
let omnes_s = omnes(cache, s, n_omnes, use_tan_omnes);
let omnes_s_tick = omnes(cache, tansub, n_omnes, use_tan_omnes);
let res = (omnes_s_tick / omnes_s).norm_sqr().ln()
/ ( (tansub - S0).sqrt() * tansub * (tansub - s) )
/ s_tick.cos().powi(2);
println!("{:?} {:?} {:?} {:?} {:?}", s_tick, tansub, omnes_s, omnes_s_tick, res);
println!("LOL {:?}", omnes(cache, tansub, n_omnes, use_tan_omnes));
res
}
pub fn phi0_integrand_notan_noxsub(cache:&mut Cache, s: f64, s_tick: f64, n_omnes:u32, use_tan_omnes: bool) -> f64 {
let omnes_s = omnes(cache, s, n_omnes, use_tan_omnes);
let omnes_s_tick = omnes(cache, s_tick, n_omnes, use_tan_omnes);
let res = (omnes_s_tick / omnes_s).norm_sqr().ln()
/ ( (s_tick - S0).sqrt() * s_tick * (s_tick - s) );
println!("{:?} {:?} {:?} {:?} {:?}", s, s_tick, omnes_s, omnes_s_tick, res);
res
}
pub fn phi0(cache:&mut Cache, s: f64, n_omnes: u32, n_phi0: u32, use_tan_omnes: bool, use_tan_phi0: bool, use_xsub: bool) -> f64 {
//let t0 = Instant::now();
if !cache.gauss_quad_lut.contains_key(&n_phi0) {
let gq_values = GaussLegendre::nodes_and_weights(n_phi0.try_into().unwrap());
cache.gauss_quad_lut.insert(n_phi0, (Rc::from(gq_values.0), Rc::from(gq_values.1)));
@ -205,7 +241,20 @@ pub fn phi0(cache:&mut Cache, s: f64, n_omnes: u32, n_phi0: u32, use_tan_omnes:
let (roots, weights) = (Rc::clone(roots), Rc::clone(weights));
let analyt = omnes(cache, s, n_omnes, use_tan_omnes).norm_sqr().ln() / S0.sqrt() / 2.0;
let intgrl = s / PI * integrate(&*roots, &*weights, 0.0, PI / 2.0, |x| phi0_integrand(cache,x,s,n_omnes, use_tan_omnes));
let intgrl = if use_tan_phi0 {
if use_xsub {
s / PI * integrate(&*roots, &*weights, 0.0, PI / 2.0, |x| phi0_integrand_tan_xsub(cache, x, s, n_omnes, use_tan_omnes))
} else {
s / PI * integrate(&*roots, &*weights, S0.atan(), PI / 2.0, |x| phi0_integrand_tan_noxsub(cache, x, s, n_omnes, use_tan_omnes))
}
} else {
if use_xsub {
s / PI * integrate(&*roots, &*weights, 0.0, INF, |x| phi0_integrand_notan_xsub(cache, x, s, n_omnes, use_tan_omnes))
} else {
s / PI * integrate(&*roots, &*weights, S0, INF, |x| phi0_integrand_notan_noxsub(cache, x, s, n_omnes, use_tan_omnes))
}
};
//println!("{:?}", t0.elapsed());
-(s-S0).sqrt() * (intgrl - analyt)
}

View File

@ -40,7 +40,7 @@ impl Default for App {
fn default() -> Self {
App {
plot_data: Vec::default(),
plots_available: ["Delta".to_string(), "Omnes Integrand".to_string(), "Omnes".to_string(), "Phi0 Integrand".to_string(), "Phi0".to_string(), "Prozentueller Fehler".to_string()],
plots_available: ["Delta".to_string(), "Omnes Integrand".to_string(), "Omnes".to_string(), "Phi0 Integrand".to_string(), "Phi0".to_string(), "Phi0 / delta".to_string()],
calc_cache: calc::Cache::default(),
scaling_type: ScalingType::default(),
a: calc::S0,
@ -66,91 +66,151 @@ impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
let cur_scaling_type = self.scaling_type;
egui::ComboBox::from_label("pick y-scaling").selected_text(format!("{:?}", self.scaling_type)).show_ui(ui, |ui| {
ui.selectable_value(&mut self.scaling_type, ScalingType::Logarithmic, "log10");
ui.selectable_value(&mut self.scaling_type, ScalingType::Linear, "linear");
});
float_text_edit_singleline(ui, &mut self.a);
float_text_edit_singleline(ui, &mut self.b);
int_text_edit_singleline(ui, &mut self.n_points);
int_text_edit_singleline(ui, &mut self.n_omnes);
int_text_edit_singleline(ui, &mut self.n_phi0);
ui.vertical_centered_justified(|ui| {
ui.horizontal(|ui| {
egui::Grid::new("grid1")
.min_col_width(125.0)
.show(ui, |ui| {
ui.label("calc interval start:").on_hover_text("the upper bound of the interval that functions are calculated in");;
float_text_edit_singleline(ui, &mut self.a);
ui.end_row();
ui.checkbox(&mut self.use_tan_omnes, "Use tan()-subst. for Omnes");
ui.checkbox(&mut self.use_tan_phi0, "Use tan()-subst. for Phi0");
ui.checkbox(&mut self.use_xsub_phi0, "Use second subst. for Phi0");
ui.label("calc interval end:").on_hover_text("the upper bound of the interval that functions are calculated in");
float_text_edit_singleline(ui, &mut self.b);
ui.end_row();
let button_clear = ui.button("Clear canvas");
if button_clear.clicked() {
self.plot_data = Vec::new();
}
ui.label("N for omnes:").on_hover_text("the number of points used in calculation of omnes function");
int_text_edit_singleline(ui, &mut self.n_omnes);
ui.end_row();
for i in 0..self.plots_available.len() {
let button = ui.button( format!("Calculate {}", self.plots_available[i].clone()));
if button.clicked() {
let x_values: Vec<f64> = (0..self.n_points).map(|x| -> f64 {f64::from(x) * ((self.b - self.a) / f64::from(self.n_points)) + self.a}).collect();
match i {
0 => {
let y_values_delta:Vec<f64> = x_values.iter().map(|&x| calc::delta_with_lut(&mut self.calc_cache, x)).collect();
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_delta.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Delta".to_string()
})
}
1 => {
let y_values_omnes_integrand: Vec<f64> = x_values.iter().map(|&x| calc::omnes_integrand(&mut self.calc_cache, x, 100.0).abs()).collect();
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_omnes_integrand.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Omnes Integrand".to_string()
})
}
2 => {
let y_values_omnes: Vec<f64> = x_values.iter().map(|&x| calc::omnes(&mut self.calc_cache, x, self.n_omnes, self.use_tan_omnes).abs().powi(2)).collect();
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_omnes.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Omnes".to_string()
})
}
3 => {
let y_values_phi0_integrand: Vec<f64> = x_values.iter().map(|&x| calc::phi0_integrand(&mut self.calc_cache, x, 10000.0, self.n_omnes, self.use_tan_omnes)).collect();
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_phi0_integrand.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Phi0 Integrand".to_string()
})
}
4 => {
let t0 = Instant::now();
let y_values_phi0: Vec<f64> = x_values.iter().map(|&x| calc::phi0(&mut self.calc_cache, x, self.n_omnes, self.n_phi0, self.use_tan_omnes, self.use_tan_phi0, self.use_xsub_phi0)).collect();
println!("{:?}", t0.elapsed());
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_phi0.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Phi0".to_string()
})
// let y_values_phi0 = calc::bit_pattern_randomness_tester(self.a, self.b, self.n_points as u64);
// self.plot_data.push(PlotCurve {
// points: (0..self.n_points).zip(y_values_phi0.iter()).map(|(x,&y)| [x as f64,y]).collect(),
// name: "Phi0".to_string()
// })
}
5 => {
let y_values_phi0: Vec<f64> = x_values.iter().map(|&x| {
let t0 = Instant::now();
let val = calc::phi0(&mut self.calc_cache, x.powi(2), self.n_omnes, self.n_phi0, self.use_tan_omnes, self.use_tan_phi0, self.use_xsub_phi0) / calc::delta_with_lut(&mut self.calc_cache, x.powi(2)) - 1.0;
println!("time for x = {}: {:?}", x, t0.elapsed());
val
}).collect();
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_phi0.iter()).map(|(&x,&y)| [x,y]).collect(),
name: "Phi0".to_string()
})
}
6_usize.. => {
panic!("Not all buttons have been assigned data!");
ui.label("N for phi0:").on_hover_text("the number of points used in calculation of phi0 function");
int_text_edit_singleline(ui, &mut self.n_phi0);
ui.end_row();
ui.label("number of plotpoints:").on_hover_text("the number of points shown in the plot");
int_text_edit_singleline(ui, &mut self.n_points);
ui.end_row();
});
ui.separator();
ui.vertical(|ui| {
ui.checkbox(&mut self.use_tan_omnes, "Use tan()-subst. for Omnes");
ui.checkbox(&mut self.use_tan_phi0, "Use tan()-subst. for phi0");
ui.checkbox(&mut self.use_xsub_phi0, "Use second subst. for phi0");
egui::ComboBox::from_label("pick y-scaling").selected_text(format!("{:?}", self.scaling_type)).show_ui(ui, |ui| {
ui.selectable_value(&mut self.scaling_type, ScalingType::Logarithmic, "log10");
ui.selectable_value(&mut self.scaling_type, ScalingType::Linear, "linear");
});
ui.horizontal(|ui| {
let button_clear = ui.button("Clear canvas");
if button_clear.clicked() {
self.plot_data = Vec::new();
}
egui::widgets::global_dark_light_mode_switch(ui);
});
});
});
ui.separator();
ui.label("You can calculate the following functions:");
ui.horizontal(|ui| {
for i in 0..self.plots_available.len() {
let button = ui.button( format!("{}", self.plots_available[i].clone()));
if button.clicked() {
let x_values: Vec<f64> = (0..self.n_points).map(|x| -> f64 {f64::from(x) * ((self.b - self.a) / f64::from(self.n_points)) + self.a}).collect();
match i {
0 => {
let y_values_delta:Vec<f64> = if self.scaling_type == ScalingType::Linear {
x_values.iter().map(|&x| calc::delta_with_lut(&mut self.calc_cache, x)).collect()
} else {
x_values.iter().map(|&x| calc::delta_with_lut(&mut self.calc_cache, x).log10()).collect()
};
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_delta.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Delta".to_string()
})
}
1 => {
let y_values_omnes_integrand:Vec<f64> = if self.scaling_type == ScalingType::Linear {
x_values.iter().map(|&x| calc::omnes_integrand_tan(&mut self.calc_cache, x, 100.0).abs()).collect()
} else {
x_values.iter().map(|&x| calc::omnes_integrand_tan(&mut self.calc_cache, x, 100.0).abs().log10()).collect()
};
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_omnes_integrand.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Omnes Integrand".to_string()
})
}
2 => {
let y_values_omnes:Vec<f64> = if self.scaling_type == ScalingType::Linear {
x_values.iter().map(|&x| calc::omnes(&mut self.calc_cache, x, self.n_omnes, self.use_tan_omnes).abs().powi(2)).collect()
} else {
x_values.iter().map(|&x| calc::omnes(&mut self.calc_cache, x, self.n_omnes, self.use_tan_omnes).abs().powi(2).log10()).collect()
};
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_omnes.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Omnes".to_string()
})
}
3 => {
let y_values_phi0_integrand:Vec<f64> = if self.scaling_type == ScalingType::Linear {
x_values.iter().map(|&x| calc::phi0_integrand_tan_xsub(&mut self.calc_cache, x, 10000.0, self.n_omnes, self.use_tan_omnes)).collect()
} else {
x_values.iter().map(|&x| calc::phi0_integrand_tan_xsub(&mut self.calc_cache, x, 10000.0, self.n_omnes, self.use_tan_omnes).log10()).collect()
};
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_phi0_integrand.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Phi0 Integrand".to_string()
})
}
4 => {
let y_values_phi0: Vec<f64> = if self.scaling_type == ScalingType::Linear {
x_values.iter().map(|&x| calc::phi0(&mut self.calc_cache, x, self.n_omnes, self.n_phi0, self.use_tan_omnes, self.use_tan_phi0, self.use_xsub_phi0)).collect()
} else {
x_values.iter().map(|&x| calc::phi0(&mut self.calc_cache, x, self.n_omnes, self.n_phi0, self.use_tan_omnes, self.use_tan_phi0, self.use_xsub_phi0).log10()).collect()
};
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_phi0.iter()).map(|(&x,&y)| [x.powf(0.5),y]).collect(),
name: "Phi0".to_string()
})
// let y_values_phi0 = calc::bit_pattern_randomness_tester(self.a, self.b, self.n_points as u64);
// self.plot_data.push(PlotCurve {
// points: (0..self.n_points).zip(y_values_phi0.iter()).map(|(x,&y)| [x as f64,y]).collect(),
// name: "Phi0".to_string()
// })
}
5 => {
let y_values_phi0: Vec<f64> = if self.scaling_type == ScalingType::Linear {
x_values.iter().map(|&x| {
let val = calc::phi0(&mut self.calc_cache, x.powi(2), self.n_omnes, self.n_phi0, self.use_tan_omnes, self.use_tan_phi0, self.use_xsub_phi0) / calc::delta_with_lut(&mut self.calc_cache, x.powi(2));
val
}).collect()
} else {
x_values.iter().map(|&x| {
let val = calc::phi0(&mut self.calc_cache, x.powi(2), self.n_omnes, self.n_phi0, self.use_tan_omnes, self.use_tan_phi0, self.use_xsub_phi0) / calc::delta_with_lut(&mut self.calc_cache, x.powi(2));
val.log10()
}).collect()
};
self.plot_data.push(PlotCurve {
points: x_values.iter().zip(y_values_phi0.iter()).map(|(&x,&y)| [x,y]).collect(),
name: "phi0 / delta".to_string()
})
}
6_usize.. => {
panic!("Not all buttons have been assigned data!");
}
}
}
}
}
}
});
});
if self.scaling_type != cur_scaling_type {
for curve in self.plot_data.iter_mut() {
@ -167,7 +227,6 @@ impl eframe::App for App {
let plot = Plot::new("my_plot")
.grid_spacing(5.0f32..=300.0f32)
.x_axis_label("sqrt(s) [GeV]")
.y_axis_label("|Omega|^2")
.legend(Legend::default());
let plot = match self.scaling_type {
@ -188,6 +247,7 @@ impl eframe::App for App {
}
};
plot.show(ui, |plot_ui| {
for i in 0..self.plot_data.len() {
plot_ui.line(Line::new(self.plot_data[i].points.clone()).name(self.plot_data[i].name.clone())); // is clone necessary?
@ -220,7 +280,7 @@ fn inverse_log_map(x:f64) -> f64 {
fn scientific_notation(x:f64, log:bool) -> String {
if log {
format!("{}*10^{}", format!(
"{:.15}", 10f64.powf(x - x.floor()))
"{:.8}", 10f64.powf(x - x.floor()))
.trim_end_matches('0').trim_end_matches('.').to_string(),
x.floor()).to_string()
} else {
@ -233,6 +293,9 @@ fn int_text_edit_singleline(ui: &mut egui::Ui, value: &mut u32) -> egui::Respons
let res = ui.text_edit_singleline(&mut tmp_value);
if let Ok(result) = tmp_value.parse::<u32>() {
*value = result;
} else if tmp_value == "" {
*value = 0;
}
res
}
@ -242,6 +305,8 @@ fn float_text_edit_singleline(ui: &mut egui::Ui, value: &mut f64) -> egui::Respo
let res = ui.text_edit_singleline(&mut tmp_value);
if let Ok(result) = tmp_value.parse::<f64>() {
*value = result;
} else if tmp_value == "" {
*value = 0.0;
}
res
}

63
calc.py
View File

@ -1,34 +1,41 @@
import math
import random
m_e = 9.10938e-31
e = 1.602e-19
pi = 3.141592
epsilon_0 = 8.854e-12
h_bar = 1.05457e-34
h=6.626e-34
c=299792458
my_B=9.274e-24
k_B=1.381e-23
avog=6.022e26
m_Kalium=39.0983/avog
# m_e = 9.10938e-31
# e = 1.602e-19
# pi = 3.141592
# epsilon_0 = 8.854e-12
# h_bar = 1.05457e-34
# h=6.626e-34
# c=299792458
# my_B=9.274e-24
# k_B=1.381e-23
# avog=6.022e26
# m_Kalium=39.0983/avog
def E(n):
return -m_e*e**4 / (2*(4*pi*epsilon_0*h_bar*n)**2)
# def E(n):
# return -m_e*e**4 / (2*(4*pi*epsilon_0*h_bar*n)**2)
def dE(n1,n2):
return -m_e*e**4 / (2*(4*pi*epsilon_0*h_bar)**2) * (1/n2**2 - 1/n1**2)
# def dE(n1,n2):
# return -m_e*e**4 / (2*(4*pi*epsilon_0*h_bar)**2) * (1/n2**2 - 1/n1**2)
def lamb(E1,E2):
return c*h*(E1-E2)**-1
# def lamb(E1,E2):
# return c*h*(E1-E2)**-1
# print(E(3))
# print(E(2))
# print(lamb(E(3),E(2)-2*my_B*2)*10**9)
Ekin = 3/2*k_B*600
v_x = math.sqrt(2*Ekin/m_Kalium)
t_acc = 0.2 / v_x
F = my_B * 2
d = 1/2*F/m_Kalium*t_acc**2
v_z_end = F/m_Kalium*t_acc
print(v_z_end/v_x)
print(1.492+0.1492)
# # print(E(3))
# # print(E(2))
# # print(lamb(E(3),E(2)-2*my_B*2)*10**9)
# Ekin = 3/2*k_B*600
# v_x = math.sqrt(2*Ekin/m_Kalium)
# t_acc = 0.2 / v_x
# F = my_B * 2
# d = 1/2*F/m_Kalium*t_acc**2
# v_z_end = F/m_Kalium*t_acc
# print(v_z_end/v_x)
# print(1.492+0.1492)
sum = 0
for i in range(18):
sum += random.randint(1,4)
print(sum)