use crate::advanced::enhanced_kriging::AnisotropicCovariance;
use crate::advanced::fast_kriging::{FastKriging, FastKrigingBuilder, FastKrigingMethod};
use crate::advanced::kriging::CovarianceFunction;
use crate::error::InterpolateResult;
use scirs2_core::ndarray::{Array1, Array2, ArrayView1, ArrayView2};
use scirs2_core::numeric::{Float, FromPrimitive};
use std::fmt::{Debug, Display};
use std::ops::{Add, Div, Mul, Sub};
#[allow(dead_code)]
pub fn make_local_kriging<
F: Float
+ FromPrimitive
+ Debug
+ Display
+ Add<Output = F>
+ Sub<Output = F>
+ Mul<Output = F>
+ Div<Output = F>
+ std::ops::AddAssign
+ std::ops::SubAssign
+ std::ops::MulAssign
+ std::ops::DivAssign
+ std::ops::RemAssign
+ 'static,
>(
points: &ArrayView2<F>,
values: &ArrayView1<F>,
cov_fn: CovarianceFunction,
length_scale: F,
max_neighbors: usize,
) -> InterpolateResult<FastKriging<F>> {
let n_dims = points.shape()[1];
let length_scales = Array1::from_elem(n_dims, length_scale);
FastKrigingBuilder::<F>::new()
.points(points.to_owned())
.values(values.to_owned())
.covariance_function(cov_fn)
.length_scales(length_scales)
.approximation_method(FastKrigingMethod::Local)
.max_neighbors(max_neighbors)
.build()
}
#[allow(dead_code)]
pub fn make_fixed_rank_kriging<
F: Float
+ FromPrimitive
+ Debug
+ Display
+ Add<Output = F>
+ Sub<Output = F>
+ Mul<Output = F>
+ Div<Output = F>
+ std::ops::AddAssign
+ std::ops::SubAssign
+ std::ops::MulAssign
+ std::ops::DivAssign
+ std::ops::RemAssign
+ 'static,
>(
points: &ArrayView2<F>,
values: &ArrayView1<F>,
cov_fn: CovarianceFunction,
length_scale: F,
rank: usize,
) -> InterpolateResult<FastKriging<F>> {
let n_dims = points.shape()[1];
let length_scales = Array1::from_elem(n_dims, length_scale);
FastKrigingBuilder::<F>::new()
.points(points.to_owned())
.values(values.to_owned())
.covariance_function(cov_fn)
.length_scales(length_scales)
.approximation_method(FastKrigingMethod::FixedRank(rank))
.build()
}
#[allow(dead_code)]
pub fn make_tapered_kriging<
F: Float
+ FromPrimitive
+ Debug
+ Display
+ Add<Output = F>
+ Sub<Output = F>
+ Mul<Output = F>
+ Div<Output = F>
+ std::ops::AddAssign
+ std::ops::SubAssign
+ std::ops::MulAssign
+ std::ops::DivAssign
+ std::ops::RemAssign
+ 'static,
>(
points: &ArrayView2<F>,
values: &ArrayView1<F>,
cov_fn: CovarianceFunction,
length_scale: F,
taper_range: F,
) -> InterpolateResult<FastKriging<F>> {
let n_dims = points.shape()[1];
let length_scales = Array1::from_elem(n_dims, length_scale);
FastKrigingBuilder::<F>::new()
.points(points.to_owned())
.values(values.to_owned())
.covariance_function(cov_fn)
.length_scales(length_scales)
.approximation_method(FastKrigingMethod::Tapering(taper_range.to_f64().expect("Operation failed")))
.build()
}
#[allow(dead_code)]
pub fn make_hodlr_kriging<
F: Float
+ FromPrimitive
+ Debug
+ Display
+ Add<Output = F>
+ Sub<Output = F>
+ Mul<Output = F>
+ Div<Output = F>
+ std::ops::AddAssign
+ std::ops::SubAssign
+ std::ops::MulAssign
+ std::ops::DivAssign
+ std::ops::RemAssign
+ 'static,
>(
points: &ArrayView2<F>,
values: &ArrayView1<F>,
cov_fn: CovarianceFunction,
length_scale: F,
leaf_size: usize,
) -> InterpolateResult<FastKriging<F>> {
let n_dims = points.shape()[1];
let length_scales = Array1::from_elem(n_dims, length_scale);
FastKrigingBuilder::<F>::new()
.points(points.to_owned())
.values(values.to_owned())
.covariance_function(cov_fn)
.length_scales(length_scales)
.approximation_method(FastKrigingMethod::HODLR(leaf_size))
.build()
}
#[allow(dead_code)]
pub fn select_approximation_method(_npoints: usize) -> FastKrigingMethod {
if _n_points < 500 {
FastKrigingMethod::Local
} else if n_points < 5_000 {
FastKrigingMethod::FixedRank(50)
} else if n_points < 50_000 {
FastKrigingMethod::Tapering(3.0)
} else {
FastKrigingMethod::HODLR(64)
}
}
#[derive(Debug, Clone)]
pub struct KrigingPerformanceStats {
pub fit_time_ms: f64,
pub predict_time_ms: f64,
pub n_points: usize,
pub n_dims: usize,
pub method: FastKrigingMethod,
}
#[cfg(feature = "std")]
#[allow(dead_code)]
pub fn benchmark_methods<
F: Float
+ FromPrimitive
+ Debug
+ Display
+ Add<Output = F>
+ Sub<Output = F>
+ Mul<Output = F>
+ Div<Output = F>
+ std::ops::AddAssign
+ std::ops::SubAssign
+ std::ops::MulAssign
+ std::ops::DivAssign
+ std::ops::RemAssign
+ 'static,
>(
points: &ArrayView2<F>,
values: &ArrayView1<F>,
cov_fn: CovarianceFunction,
length_scale: F,
) -> Vec<KrigingPerformanceStats> {
use std::time::Instant;
let n_points = points.shape()[0];
let n_dims = points.shape()[1];
let methods = vec![
FastKrigingMethod::Local,
FastKrigingMethod::FixedRank(std::cmp::min(50, n_points / 10)),
FastKrigingMethod::Tapering(3.0),
FastKrigingMethod::HODLR(32),
];
let length_scales = Array1::from_elem(n_dims, length_scale);
let n_query = std::cmp::min(100, n_points / 10);
let mut query_points = Array2::zeros((n_query, n_dims));
let stride = n_points / n_query;
for i in 0..n_query {
let idx = i * stride;
query_points
.slice_mut(scirs2_core::ndarray::s![i, ..])
.assign(&points.slice(scirs2_core::ndarray::s![idx, ..]));
}
let mut stats = Vec::new();
for method in methods {
let start = Instant::now();
let model_result = FastKrigingBuilder::<F>::new()
.points(points.to_owned())
.values(values.to_owned())
.covariance_function(cov_fn)
.length_scales(length_scales.clone())
.approximation_method(method)
.build();
let fit_time = start.elapsed().as_secs_f64() * 1000.0;
if let Ok(model) = model_result {
let start = Instant::now();
let _ = model.predict(&query_points.view());
let predict_time = start.elapsed().as_secs_f64() * 1000.0 / n_query as f64;
stats.push(KrigingPerformanceStats {
fit_time_ms: fit_time,
predict_time_ms: predict_time,
n_points,
n_dims,
method,
});
}
}
stats
}