use faer::MatRef;
use ann_search_rs::prelude::AnnSearchFloat;
use crate::errors::BixverseErrors;
use crate::methods::nmf_hals::consensus::*;
use crate::methods::nmf_hals::dense::DenseInput;
use crate::methods::nmf_hals::nmf_preprocessing::*;
use crate::methods::nmf_hals::*;
use crate::prelude::BixverseFloat;
fn resolve_preprocessing(preprocessing: &str) -> NmfPreprocessing {
parse_nmf_processing(preprocessing).unwrap_or_else(|| {
println!(
"Unknown string provided: {:?}. Using the default (No additional pre-processing)",
preprocessing
);
NmfPreprocessing::default()
})
}
pub fn nmf_single_run<T>(
data: MatRef<T>,
k: usize,
preprocessing: &str,
nmf_hals_params: Option<HalsOpts<T>>,
verbose: usize,
) -> Result<NmfResult<T>, BixverseErrors>
where
T: BixverseFloat,
{
let hals_opt = nmf_hals_params.unwrap_or_default();
let data_processed = nmf_process_dense(data, &resolve_preprocessing(preprocessing));
let nmf_input = DenseInput::new(data_processed.as_ref())?;
let nmf_res = nmf_hals(&nmf_input, k, &hals_opt, verbose)?;
Ok(nmf_res)
}
pub fn nmf_multiple_run<T>(
data: MatRef<T>,
k: usize,
preprocessing: &str,
nmf_hals_params: Option<HalsOpts<T>>,
n_runs: usize,
base_seed: usize,
verbose: usize,
) -> Result<StabilisedNmfResult<T>, BixverseErrors>
where
T: BixverseFloat,
{
let hals_opt = nmf_hals_params.unwrap_or_default();
let data_processed = nmf_process_dense(data, &resolve_preprocessing(preprocessing));
let nmf_input = DenseInput::new(data_processed.as_ref())?;
let res = stabilised_nmf(&nmf_input, k, n_runs, base_seed as u64, &hals_opt, verbose)?;
Ok(res)
}
#[allow(clippy::too_many_arguments)]
pub fn nmf_consensus_run<T>(
data: MatRef<T>,
k: usize,
preprocessing: &str,
nmf_hals_params: Option<HalsOpts<T>>,
consensus_params: Option<ConsensusParams<T>>,
n_runs: usize,
base_seed: usize,
verbose: usize,
) -> Result<ConsensusNmfResult<T>, BixverseErrors>
where
T: BixverseFloat + AnnSearchFloat,
{
let hals_opt = nmf_hals_params.unwrap_or_default();
let data_processed = nmf_process_dense(data, &resolve_preprocessing(preprocessing));
let nmf_input = DenseInput::new(data_processed.as_ref())?;
nmf_consensus(
&nmf_input,
k,
n_runs,
base_seed as u64,
&hals_opt,
consensus_params,
verbose,
)
}
#[allow(clippy::too_many_arguments)]
pub fn nmf_k_sweep_run<T>(
data: MatRef<T>,
k_range: &[usize],
preprocessing: &str,
nmf_hals_params: Option<HalsOpts<T>>,
consensus_params: Option<ConsensusParams<T>>,
n_runs: usize,
base_seed: usize,
verbose: usize,
) -> Result<Vec<KSweepEntry<T>>, BixverseErrors>
where
T: BixverseFloat + AnnSearchFloat,
{
let hals_opt = nmf_hals_params.unwrap_or_default();
let data_processed = nmf_process_dense(data, &resolve_preprocessing(preprocessing));
let nmf_input = DenseInput::new(data_processed.as_ref())?;
nmf_k_sweep(
&nmf_input,
k_range,
n_runs,
base_seed as u64,
&hals_opt,
consensus_params,
verbose,
)
}