///|
/// MOFA2 multi-omics factor analysis demo.
/// Demonstrates sparse Bayesian factor analysis on multi-omics data.
fn main {
println("=== MOFA2 Multi-Omics Factor Analysis Demo ===")
println("")
// Create example data (RNA-seq + ATAC-seq)
let n_samples = 50
let views = @bio.mofa_create_example(n_samples, 5)
println(
"Input: \{n_samples.to_string()} samples, \{views.length().to_string()} omics views",
)
{
let mut i = 0
while i < views.length() {
let view = views[i]
println(
" View \{i.to_string()}: \{view.view_name} (\{view.n_features().to_string()} features)",
)
i = i + 1
}
}
// Configure MOFA2
let params = @bio.MofaParams::create(
n_factors=5,
max_iterations=100,
tolerance=0.01,
seed=42,
)
// Run MOFA2
println("")
println("Running MOFA2 (EM algorithm)...")
let result = @bio.mofa_run(views, params)
println("")
println("Results:")
println(" Active factors: \{result.active_factors.to_string()}/5")
println(" Iterations: \{result.n_iterations.to_string()}")
println(" Converged: \{result.converged.to_string()}")
// Print factor variance explained
println("")
println("Variance explained per factor:")
{
let mut f = 0
while f < result.factor_vars.length() {
let pct = result.factor_vars[f] * 100.0
println(" Factor \{(f + 1).to_string()}: \{pct.to_string()}%")
f = f + 1
}
}
// Print variance explained per view
println("")
println("Total variance explained per view:")
{
let mut vi = 0
while vi < result.view_vars.length() {
let view = views[vi]
let mut sum = 0.0
for v in result.view_vars[vi] {
sum = sum + v
}
let pct = sum * 100.0
println(" \{view.view_name}: \{pct.to_string()}%")
vi = vi + 1
}
}
// Print sample factors (first 5 samples)
println("")
println("Factor activations (first 5 samples):")
{
let mut s = 0
while s < 5 && s < result.factors.length() {
let mut line = " Sample " + (s + 1).to_string() + ": ["
let mut f = 0
while f < result.factors[s].length() {
if f > 0 {
line = line + ", "
}
line = line + result.factors[s][f].to_string()
f = f + 1
}
line = line + "]"
println(line)
s = s + 1
}
}
println("")
println("Done!")
}