///|
fn main {
println("=== Bioconductor-style PCAtools Demo ===\n")
println("--- 1. Run PCA on sample data ---")
let data = [
[1.0, 2.0, 3.0],
[2.0, 4.0, 5.0],
[3.0, 6.0, 7.0],
[4.0, 8.0, 9.0],
[5.0, 10.0, 11.0],
[6.0, 12.0, 10.0],
[7.0, 14.0, 8.0],
[8.0, 16.0, 5.0],
[9.0, 18.0, 3.0],
[50.0, 50.0, 50.0], // outlier
]
let n_rows = data.length()
let n_cols = if n_rows > 0 { data[0].length() } else { 0 }
println(" Input: \{n_rows} samples x \{n_cols} variables")
let res = @bio.pcatools_run_pca(data, 3, true)
println(@bio.pcatools_summary(res))
println("\n--- 2. Scree plot (ASCII) ---")
let scree = @bio.scree_plot_ascii(res, height=10, width_per_pc=6)
println(scree)
println("\n--- 3. Biplot (ASCII) ---")
let opts = @bio.BiplotOptions::new()
let biplot = @bio.pca_biplot_ascii(res, opts~)
println(biplot)
println("\n--- 4. Outlier detection ---")
let outlier_res = @bio.find_pca_outliers(res, n_pcs=2, quantile_cutoff=0.9)
println(" Tested samples: \{outlier_res.n_tested}")
println(" Distance cutoff: \{outlier_res.cutoff}")
let n_outliers = outlier_res.indices.length()
println(" Outliers found: \{n_outliers}")
if outlier_res.indices.length() > 0 {
let mut idxs = " Outlier indices: [".to_string()
let mut oi = 0
while oi < outlier_res.indices.length() {
if oi > 0 {
idxs = idxs + ", "
}
idxs = idxs + outlier_res.indices[oi].to_string()
oi = oi + 1
}
idxs = idxs + "]"
println(idxs)
}
println("\n--- 5. Variable Correlations with PCs ---")
let corr = @bio.variable_correlations(data, res, which_pcs=2)
let cr = corr.length()
let cc = if cr > 0 { corr[0].length() } else { 0 }
println(" Variables x PCs shape: \{cr} x \{cc}")
let mut vi = 0
while vi < corr.length() {
let row = corr[vi]
let mut s = " var_\{vi + 1} vs PCs: [".to_string()
let mut pj = 0
while pj < row.length() {
if pj > 0 {
s = s + ", "
}
s = s + row[pj].to_string()
pj = pj + 1
}
s = s + "]"
println(s)
vi = vi + 1
}
println("\nPCAtools demo completed successfully!")
}