1pub fn run_chem_smiles(smiles: &str) {
7 use qualia_core_db::domains::chemical::organic_chemistry::{
8 compute_descriptors, compute_logp, compute_tpsa, evaluate_lipinski, exact_molecular_weight,
9 formula_string, parse_smiles,
10 };
11 let mol = parse_smiles(smiles);
12 let desc = compute_descriptors(&mol);
13 println!("SMILES: {smiles}");
14 println!(" Formula : {}", formula_string(&mol));
15 println!(" Exact MW : {:.4} Da", exact_molecular_weight(&mol));
16 println!(" LogP : {:.4}", compute_logp(&mol));
17 println!(" TPSA : {:.4} Ų", compute_tpsa(&mol));
18 println!(" HBA : {}", desc.hb_acceptors);
19 println!(" HBD : {}", desc.hb_donors);
20 println!(" Rot bonds: {}", desc.rotatable_bonds);
21 let lip = evaluate_lipinski(&desc);
22 println!(
23 " Lipinski : {} (violations: {})",
24 if lip.passes { "PASS" } else { "FAIL" },
25 lip.violations
26 );
27}
28
29pub fn run_chem_thermo(reaction: &str, a: f64, b: f64, c: f64) {
30 use qualia_core_db::domains::chemical::organic_chemistry::{
31 arrhenius_rate, gibbs_free_energy, henderson_hasselbalch,
32 };
33 match reaction.to_ascii_lowercase().as_str() {
34 "arrhenius" => {
35 let rate = arrhenius_rate(a, b, c);
37 println!("Arrhenius rate: k = {rate:.6e} s⁻¹");
38 println!(" A={a:.3e}, Ea={b:.3e} J/mol, T={c} K");
39 }
40 "gibbs" => {
41 let dg = gibbs_free_energy(a * 1000.0, b, c);
43 println!(
44 "Gibbs free energy: ΔG = {dg:.4} J/mol ({:.4} kJ/mol)",
45 dg / 1000.0
46 );
47 println!(" ΔH={a} kJ/mol, ΔS={b} J/mol·K, T={c} K");
48 println!(
49 " Spontaneous: {}",
50 if dg < 0.0 {
51 "yes (ΔG < 0)"
52 } else {
53 "no (ΔG ≥ 0)"
54 }
55 );
56 }
57 "henderson-hasselbalch" | "hh" => {
58 let ph = henderson_hasselbalch(a, b, c);
60 println!("Henderson-Hasselbalch: pH = {ph:.4}");
61 println!(" pKa={a}, [base]={b} M, [acid]={c} M");
62 }
63 other => {
64 eprintln!("Unknown reaction '{other}'. Use: arrhenius | gibbs | henderson-hasselbalch")
65 }
66 }
67}
68
69pub fn run_chem_druglike(smiles: &str) {
70 use qualia_core_db::domains::chemical::organic_chemistry::{
71 compute_descriptors, compute_logp, compute_tpsa, evaluate_egan, evaluate_ghose,
72 evaluate_lipinski, evaluate_veber, parse_smiles, predict_bbb_permeation,
73 };
74 let mol = parse_smiles(smiles);
75 let desc = compute_descriptors(&mol);
76 let logp = compute_logp(&mol);
77 let tpsa = compute_tpsa(&mol);
78 let lip = evaluate_lipinski(&desc);
79 let veb = evaluate_veber(&desc);
80 let gho = evaluate_ghose(&desc);
81 let ega = evaluate_egan(&desc);
82 let bbb = predict_bbb_permeation(desc.molecular_weight, logp, tpsa, desc.hb_donors);
83 println!("Drug-likeness for SMILES: {smiles}");
84 println!(
85 " Lipinski : {} (violations: {})",
86 if lip.passes { "PASS" } else { "FAIL" },
87 lip.violations
88 );
89 println!(" Veber : {}", if veb.passes { "PASS" } else { "FAIL" });
90 println!(" Ghose : {}", if gho.passes { "PASS" } else { "FAIL" });
91 println!(" Egan : {}", if ega.passes { "PASS" } else { "FAIL" });
92 println!(
93 " BBB : {} (MPO score: {})",
94 if bbb.is_cns_penetrant {
95 "CNS-penetrant"
96 } else {
97 "non-penetrant"
98 },
99 bbb.clark_score
100 );
101}
102
103pub fn run_chem_pka(pka: f64, conc_base: f64, conc_acid: f64) {
104 use qualia_core_db::domains::chemical::organic_chemistry::{
105 henderson_hasselbalch, ionisation_fraction,
106 };
107 let ph = henderson_hasselbalch(pka, conc_base, conc_acid);
108 let frac = ionisation_fraction(ph, pka);
109 println!("Henderson-Hasselbalch:");
110 println!(" pKa={pka}, [A⁻]={conc_base} M, [HA]={conc_acid} M");
111 println!(" pH = {ph:.4}");
112 println!(" Ionised fraction= {frac:.4}");
113}
114
115pub fn run_bio_align(query: &str, target: &str, mode: &str) {
118 use qualia_core_db::domains::biological::bioinformatics::{align_nucleotide, align_protein};
119 let q = query.as_bytes();
120 let t = target.as_bytes();
121 let result = match mode.to_ascii_lowercase().as_str() {
122 "protein" | "aa" => align_protein(q, t),
123 _ => align_nucleotide(q, t),
124 };
125 println!("Sequence alignment ({mode}):");
126 println!(" Query : {query}");
127 println!(" Target : {target}");
128 println!(" Score : {}", result.score);
129 println!(" Aligned: {}", result.aligned_query.len());
130 println!(" Gaps : {}", result.num_gaps);
131 println!(" Matches: {}", result.num_matches);
132}
133
134pub fn run_bio_kmer(sequence: &str, k: usize) {
135 use qualia_core_db::domains::biological::bioinformatics::kmer_frequencies;
136 let freqs = kmer_frequencies(sequence.as_bytes(), k);
137 println!(
138 "k-mer frequencies (k={k}) for sequence len={}:",
139 sequence.len()
140 );
141 println!(" Distinct k-mers: {}", freqs.len());
142 for (hash, count) in freqs.iter().take(8) {
143 println!(" 0x{hash:016x} → {count}");
144 }
145 if freqs.len() > 8 {
146 println!(" … ({} total)", freqs.len());
147 }
148}
149
150pub fn run_bio_translate(dna: &str) {
151 use qualia_core_db::domains::biological::bioinformatics::translate_dna_to_protein;
152 let dna_bytes = dna.as_bytes();
153 let mut protein_buf = vec![0u8; dna_bytes.len() / 3 + 1];
154 let n = translate_dna_to_protein(dna_bytes, &mut protein_buf);
155 let protein = std::str::from_utf8(&protein_buf[..n]).unwrap_or("(invalid UTF-8)");
156 println!("DNA → protein translation:");
157 println!(" DNA : {}", &dna[..dna.len().min(60)]);
158 println!(" Protein: {protein} ({n} aa)");
159}
160
161pub fn run_bio_isoelectric(protein: &str) {
162 use qualia_core_db::domains::biological::bioinformatics::calculate_isoelectric_point;
163 let pi = calculate_isoelectric_point(protein.as_bytes());
164 println!(
165 "Isoelectric point for protein '{}':",
166 &protein[..protein.len().min(20)]
167 );
168 println!(" pI = {pi:.4}");
169}
170
171pub fn run_bio_jaccard(sketch_a: &str, sketch_b: &str) {
172 use qualia_core_db::domains::biological::bioinformatics::jaccard_similarity;
173 let parse_hashes = |s: &str| -> Vec<u64> {
174 s.split(',')
175 .filter_map(|t| {
176 let t = t.trim();
177 if t.starts_with("0x") || t.starts_with("0X") {
178 u64::from_str_radix(&t[2..], 16).ok()
179 } else {
180 t.parse::<u64>().ok()
181 }
182 })
183 .collect()
184 };
185 let a = parse_hashes(sketch_a);
186 let b = parse_hashes(sketch_b);
187 let j = jaccard_similarity(&a, &b);
188 println!("Jaccard similarity:");
189 println!(" |sketch A| = {}, |sketch B| = {}", a.len(), b.len());
190 println!(" J(A,B) = {j:.6}");
191}
192
193pub fn run_bio_minhash(sequence: &str, k: usize, sketch_size: usize) {
194 use qualia_core_db::domains::biological::bioinformatics::minhash_sketch;
195 let sketch = minhash_sketch(sequence.as_bytes(), k, sketch_size);
196 println!("MinHash sketch (k={k}, size={sketch_size}):");
197 println!(" Sequence len: {}", sequence.len());
198 for h in sketch.iter().take(5) {
199 println!(" 0x{h:016x}");
200 }
201 if sketch.len() > 5 {
202 println!(" … ({} total)", sketch.len());
203 }
204}
205
206pub fn run_geo_embed_h3(index: u64) {
209 use qualia_core_db::domains::geospatial::spatial::embed_h3_context;
210 let context = embed_h3_context(index, 0, 0);
211 println!("H3 index embedding:");
212 println!(" Input : 0x{index:016x}");
213 println!(" Context: 0x{context:016x}");
214}
215
216pub fn run_thermo_gibbs(enthalpy: f64, entropy: f64, temp: f64) {
219 use qualia_core_db::domains::physical::thermodynamics::ThermodynamicSampler;
220 let sampler = ThermodynamicSampler::new(temp, 1);
221 let dg = sampler.calculate_gibbs_free_energy(enthalpy, entropy);
222 println!("Gibbs free energy:");
223 println!(" H={enthalpy:.4} J, S={entropy:.4} J/K, T={temp:.1} K");
224 println!(" ΔG = H - TS = {dg:.6} J");
225 println!(" Spontaneous: {}", if dg < 0.0 { "yes" } else { "no" });
226}
227
228pub fn run_thermo_anneal(initial_temp: f64, particles: usize, proposed_energy: f64, random: f64) {
229 use qualia_core_db::domains::physical::thermodynamics::ThermodynamicSampler;
230 let mut sampler = ThermodynamicSampler::new(initial_temp, particles);
231 let accepted = sampler.metropolis_step(proposed_energy, random);
232 println!("Metropolis-Hastings step:");
233 println!(" T_init={initial_temp} K, particles={particles}");
234 println!(" Proposed ΔE = {proposed_energy:.6}");
235 println!(" Uniform u = {random:.6}");
236 println!(" Accepted : {accepted}");
237}
238
239fn parse_vec3(s: &str) -> Option<[f32; 3]> {
242 let v: Vec<f32> = s.split(',').filter_map(|t| t.trim().parse().ok()).collect();
243 if v.len() >= 3 {
244 Some([v[0], v[1], v[2]])
245 } else {
246 eprintln!(
247 "Need 3 comma-separated values for a vector, got {}.",
248 v.len()
249 );
250 None
251 }
252}
253
254pub fn run_geometric_cross(a_str: &str, b_str: &str) {
255 use qualia_core_db::geometric_algebra::utils::{cross_product, dot_product};
256 let (Some(a), Some(b)) = (parse_vec3(a_str), parse_vec3(b_str)) else {
257 return;
258 };
259 let cross = cross_product(&a, &b);
260 let dot = dot_product(&a, &b);
261 println!("Geometric algebra:");
262 println!(" a = [{:.4}, {:.4}, {:.4}]", a[0], a[1], a[2]);
263 println!(" b = [{:.4}, {:.4}, {:.4}]", b[0], b[1], b[2]);
264 println!(
265 " a×b = [{:.6}, {:.6}, {:.6}]",
266 cross[0], cross[1], cross[2]
267 );
268 println!(" a·b = {dot:.6}");
269}
270
271pub fn run_geometric_angle(a_str: &str, b_str: &str) {
272 use qualia_core_db::geometric_algebra::utils::{angle_between_vectors, rad_to_deg};
273 let (Some(a), Some(b)) = (parse_vec3(a_str), parse_vec3(b_str)) else {
274 return;
275 };
276 let angle_rad = angle_between_vectors(&a, &b);
277 let angle_deg = rad_to_deg(angle_rad);
278 println!("Angle between vectors:");
279 println!(" a = [{:.4}, {:.4}, {:.4}]", a[0], a[1], a[2]);
280 println!(" b = [{:.4}, {:.4}, {:.4}]", b[0], b[1], b[2]);
281 println!(" θ = {angle_rad:.6} rad ({angle_deg:.4}°)");
282}
283
284pub fn run_clinical_framingham(
287 age: u8,
288 sex_male: bool,
289 total_chol: f64,
290 hdl_chol: f64,
291 systolic_bp: f64,
292 bp_treated: bool,
293 smoker: bool,
294 diabetic: bool,
295) {
296 use qualia_core_db::clinical_engine::{framingham_10yr_risk, FraminghamInput};
297 let input = FraminghamInput {
298 age,
299 sex_male,
300 total_cholesterol_mmol: total_chol,
301 hdl_cholesterol_mmol: hdl_chol,
302 systolic_bp,
303 bp_treated,
304 current_smoker: smoker,
305 diabetic,
306 };
307 let r = framingham_10yr_risk(&input);
308 println!("Framingham 10-year CVD risk:");
309 println!(
310 " Age={age}, sex={}, TC={total_chol:.2} mmol/L, HDL={hdl_chol:.2}, SBP={systolic_bp:.0}",
311 if sex_male { "M" } else { "F" }
312 );
313 println!(" Treated={bp_treated}, Smoker={smoker}, Diabetic={diabetic}");
314 println!(" Risk : {:.1}%", r.risk_10yr * 100.0);
315 println!(" Category : {:?}", r.category);
316 println!(" Log score: {:.4}", r.log_score);
317}
318
319pub fn run_clinical_sofa(
320 pao2_fio2: f64,
321 platelets: f64,
322 bilirubin: f64,
323 map: f64,
324 gcs: u8,
325 creatinine: f64,
326) {
327 use qualia_core_db::clinical_engine::{sofa_score, SofaInput};
328 let input = SofaInput {
329 pao2_fio2_ratio: pao2_fio2,
330 platelets_10_9_l: platelets,
331 bilirubin_mg_dl: bilirubin,
332 map_mmhg: map,
333 dopamine_dose: 0.0,
334 epinephrine_dose: 0.0,
335 norepinephrine_dose: 0.0,
336 glasgow_coma_scale: gcs,
337 creatinine_mg_dl: creatinine,
338 urine_output_ml_d: 500.0,
339 };
340 let score = sofa_score(&input);
341 println!("SOFA score (Sequential Organ Failure Assessment):");
342 println!(" PaO₂/FiO₂={pao2_fio2}, Platelets={platelets}×10⁹/L");
343 println!(" Bilirubin={bilirubin} mg/dL, MAP={map} mmHg, GCS={gcs}");
344 println!(" Creatinine={creatinine} mg/dL");
345 println!(" SOFA score: {score}/24");
346 let mortality = match score {
347 0..=1 => "<10%",
348 2..=3 => "~10%",
349 4..=5 => "~20%",
350 6..=7 => "~20–30%",
351 8..=9 => "~40%",
352 10..=11 => "~40–50%",
353 12..=14 => ">50%",
354 _ => ">80%",
355 };
356 println!(" Est. mortality: {mortality}");
357}
358
359pub fn run_clinical_ckd(age: u8, sex_male: bool, weight_kg: f64, creatinine: f64) {
360 use qualia_core_db::clinical_engine::{ckd_epi_egfr, cockcroft_gault_crcl, RenalInput};
361 let input = RenalInput {
362 age,
363 sex_male,
364 weight_kg,
365 serum_creatinine: creatinine,
366 };
367 let crcl = cockcroft_gault_crcl(&input);
368 let egfr = ckd_epi_egfr(&input);
369 println!("Renal function:");
370 println!(
371 " Age={age}, sex={}, weight={weight_kg} kg, Cr={creatinine} mg/dL",
372 if sex_male { "M" } else { "F" }
373 );
374 println!(" CrCl (Cockcroft-Gault) : {crcl:.1} mL/min");
375 println!(" eGFR (CKD-EPI 2021) : {egfr:.1} mL/min/1.73m²");
376 let stage = match egfr as u32 {
377 90..=u32::MAX => "G1 (normal)",
378 60..=89 => "G2 (mildly decreased)",
379 45..=59 => "G3a (mild-moderate)",
380 30..=44 => "G3b (moderate-severe)",
381 15..=29 => "G4 (severe)",
382 _ => "G5 (kidney failure)",
383 };
384 println!(" CKD stage : {stage}");
385}
386
387pub fn run_clinical_pk(dose_mg: f64, vd_l: f64, cl_l_hr: f64, time_hr: f64) {
388 use qualia_core_db::clinical_engine::{one_compartment_pk_model, PkOneCompartmentInput};
389 let input = PkOneCompartmentInput {
390 dose_mg,
391 volume_distribution_l: vd_l,
392 clearance_l_hr: cl_l_hr,
393 time_hr,
394 };
395 let r = one_compartment_pk_model(&input);
396 println!("1-compartment PK model (IV bolus):");
397 println!(" Dose={dose_mg} mg, Vd={vd_l} L, CL={cl_l_hr} L/hr");
398 println!(" C(t={time_hr}h) = {:.4} mg/L", r.concentration);
399 println!(" Half-life = {:.4} hr", r.half_life_hr);
400}
401
402pub fn run_clinical_drug_interactions(drug_names: &str) {
403 use qualia_core_db::clinical_engine::check_drug_interactions;
404 use qualia_core_db::mini_parser::hash_token;
405 let hashes: Vec<u64> = drug_names
406 .split(',')
407 .map(|s| hash_token(s.trim()))
408 .collect();
409 let interactions = check_drug_interactions(&hashes);
410 println!("Drug interaction screening for: {drug_names}");
411 if interactions.is_empty() {
412 println!(" No known interactions found.");
413 } else {
414 for ix in &interactions {
415 println!(
416 " [{:?}] 0x{:x} ↔ 0x{:x}: {}",
417 ix.severity, ix.drug_a, ix.drug_b, ix.mechanism
418 );
419 }
420 }
421}
422
423pub fn run_economics_gbm(price: f64, drift: f64, vol: f64, horizon: f64, steps: usize) {
426 use qualia_core_db::domains::financial::economics::simulate_gbm_path;
427 let final_price = simulate_gbm_path(price, drift, vol, horizon, steps);
428 println!("Geometric Brownian Motion path:");
429 println!(" S₀={price}, μ={drift}, σ={vol}, T={horizon}, steps={steps}");
430 println!(" S(T) ≈ {final_price:.4}");
431 let expected = price * (drift * horizon).exp();
432 println!(" E[S(T)] = {expected:.4} (drift-only estimate)");
433}
434
435pub fn run_economics_var(
436 price: f64,
437 drift: f64,
438 vol: f64,
439 horizon: f64,
440 steps: usize,
441 paths: usize,
442) {
443 use qualia_core_db::domains::financial::economics::run_monte_carlo_var;
444 println!("Monte Carlo VaR (paths={paths}, steps={steps})…");
445 let (mean, var95) = run_monte_carlo_var(price, drift, vol, horizon, steps, paths);
446 println!(" S₀={price}, μ={drift}, σ={vol}, T={horizon}");
447 println!(" Mean end value : {mean:.4}");
448 println!(" 95% VaR (loss) : {var95:.4}");
449}
450
451pub fn run_economics_macro(
452 m0: f64,
453 p0: f64,
454 velocity: f64,
455 real_gdp: f64,
456 horizon: f64,
457 steps: usize,
458) {
459 use qualia_core_db::domains::financial::economics::simulate_macroeconomic_flow;
460 let state = simulate_macroeconomic_flow(m0, p0, velocity, real_gdp, horizon, steps);
461 println!("Macroeconomic flow (M×V = P×Q):");
462 println!(" M₀={m0}, P₀={p0}, V={velocity}, Q={real_gdp}, T={horizon}");
463 if state.values.len() >= 2 {
464 println!(" M(T) = {:.4}", state.values[0]);
465 println!(" P(T) = {:.4}", state.values[1]);
466 println!(
467 " Implied Q = {:.4}",
468 (state.values[0] * velocity) / state.values[1]
469 );
470 }
471}
472
473pub fn run_economics_bond(face: f64, coupon_rate: f64, y: f64, n: u32) {
474 use qualia_core_db::specialized_libs::computational_economics::fixed_income::coupon_bond_price;
475 match coupon_bond_price(face, coupon_rate, y, n as f64, 1) {
476 Ok(p) => {
477 println!("Coupon bond price (face={face}, c={coupon_rate}, y={y}, n={n}): {p:.4}");
478 println!(" (clean price, par=100 equivalent would be face)");
479 }
480 Err(_) => println!("Bond pricing failed (invalid inputs)."),
481 }
482}
483
484pub fn run_economics_paper(qty: f64, last: f64) {
485 use qualia_core_db::specialized_libs::computational_economics::paper_trading::{
486 simulate_fills_against_snapshots, submit_paper_order, Fill, MarketSnapshot, OrderType,
487 PaperOrder, Side,
488 };
489 let mut book: [PaperOrder; 8] = [PaperOrder {
490 id: 0,
491 side: Side::Buy,
492 order_type: OrderType::Market,
493 qty: 0.0,
494 limit_price: 0.0,
495 stop_price: 0.0,
496 filled_qty: 0.0,
497 avg_fill_price: 0.0,
498 status: 0,
499 }; 8];
500 let mut next_id = 1u64;
501 if submit_paper_order(
502 &mut book,
503 &mut next_id,
504 Side::Buy,
505 OrderType::Market,
506 qty,
507 0.0,
508 0.0,
509 )
510 .is_ok()
511 {
512 let snaps = [MarketSnapshot {
513 bid: last - 0.1,
514 ask: last + 0.1,
515 last,
516 volume: 500.0,
517 }];
518 let mut fills: [Fill; 8] = [Fill {
519 order_id: 0,
520 qty: 0.0,
521 price: 0.0,
522 fee: 0.0,
523 }; 8];
524 let _ = simulate_fills_against_snapshots(&mut book, &snaps, 0.001, &mut fills);
525 println!("Paper trade demo: market buy {qty} @~{last}");
526 println!(" (simulation only; no real execution or ledger mutation)");
527 } else {
528 println!("Paper order submit failed.");
529 }
530}
531
532pub fn run_economics_welfare(incomes_str: &str) {
533 use qualia_core_db::specialized_libs::computational_economics::welfare::{
534 atkinson_inequality, gini_coefficient,
535 };
536 let incomes: Vec<f64> = incomes_str
537 .split(',')
538 .filter_map(|s| s.trim().parse().ok())
539 .collect();
540 if incomes.is_empty() {
541 println!("Invalid incomes");
542 return;
543 }
544 if let Ok(g) = gini_coefficient(&incomes) {
545 println!("Gini: {g:.4}");
546 }
547 if let Ok(a) = atkinson_inequality(&incomes, 1.0) {
548 println!("Atkinson (eps=1): {a:.4}");
549 }
550}
551
552pub fn run_economics_game(a: f64) {
553 use qualia_core_db::specialized_libs::computational_economics::game_theory::cournot_duopoly;
554 match cournot_duopoly(a, 1.0, 1.0, 1.0) {
555 Ok((q1, q2, p)) => {
556 let pi1 = (p - 1.0) * q1;
558 let pi2 = (p - 1.0) * q2;
559 println!(
560 "Cournot duopoly (a={a}): q1={q1:.2} q2={q2:.2} p={p:.2} pi1={pi1:.2} pi2={pi2:.2}"
561 );
562 }
563 Err(e) => println!("Cournot duopoly (a={a}): no equilibrium ({e:?})"),
564 }
565}