1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (c) 2023 Jonas Bosse
//
// Licensed under the MIT license
//! The ndarray-interp crate provides interpolation algorithms
//! for interpolating _n_-dimesional data.
//!
//! # 1D Interpolation
//! The [interp1d] module provides the [`Interp1D`](interp1d::Interp1D) interpolator
//! and different interpolation strategies
//!
//! **1D Strategies**
//! - [`interp1d::Linear`] - Linear interpolation and extrapolation
//! - [`interp1d::cubic_spline`] - Cubic Spline interpolation with different boundary conditions.
//!
//! # 2D Interpolation
//! The [interp2d] module provides the [`Interp2D`](interp2d::Interp2D) interpolator
//! and different interpolation strategies
//!
//! **2D Strategies**
//! - [`interp2d::Bilinear`] - Bilinear interpolation and extrapolation
//!
//! # Custom interpolation strategy
//! This crate defines traits to allow implementation of user
//! defined interpolation algorithms.
//! A 1D interpolation strategy can be created by implementing the
//! [`Interp1DStrategy`](interp1d::Interp1DStrategy) and
//! [`Interp1DStrategyBuilder`](interp1d::Interp1DStrategyBuilder) traits.
//! A 2D interpolation strategy can be created by implementing the
//! [`Interp2DStrategy`](interp2d::Interp2DStrategy) and
//! [`Interp2DStrategyBuilder`](interp2d::Interp2DStrategyBuilder) traits.
//!
//! See also the `custom_strategy.rs` example.
//!
//! # Examples
//! **1D Example**
//! ``` rust
//! use ndarray_interp::interp1d::*;
//! use ndarray::*;
//!
//! let data = array![0.0, 1.0, 1.5, 1.0, 0.0 ];
//! let interp = Interp1DBuilder::new(data).build().unwrap();
//!
//! let result = interp.interp_scalar(3.5).unwrap();
//! assert!(result == 0.5);
//! let result = interp.interp_array(&array![0.0, 0.5, 1.5]).unwrap();
//! assert!(result == array![0.0, 0.5, 1.25])
//! ```
//!
//! **1D Example with multidimensional data**
//! ```rust
//! use ndarray_interp::interp1d::*;
//! use ndarray::*;
//!
//! let data = array![
//! [0.0, 1.0],
//! [1.0, 2.0],
//! [1.5, 2.5],
//! [1.0, 2.0],
//! ];
//! let x = array![1.0, 2.0, 3.0, 4.0];
//!
//! let interp = Interp1D::builder(data)
//! .strategy(Linear::new().extrapolate(true))
//! .x(x)
//! .build().unwrap();
//!
//! let result = interp.interp(0.5).unwrap();
//! assert!(result == array![-0.5, 0.5]);
//! let result = interp.interp_array(&array![0.5, 4.0]).unwrap();
//! assert!(result == array![[-0.5, 0.5], [1.0, 2.0]]);
//! ```
//!
//! **2D Example**
//! ```rust
//! use ndarray_interp::interp2d::*;
//! use ndarray::*;
//!
//! let data = array![
//! [1.0, 2.0, 2.5],
//! [3.0, 4.0, 3.5],
//! ];
//! let interp = Interp2D::builder(data).build().unwrap();
//!
//! let result = interp.interp_scalar(0.0, 0.5).unwrap();
//! assert!(result == 1.5);
//! let result = interp.interp_array(&array![0.0, 1.0], &array![0.5, 2.0]).unwrap();
//! assert!(result == array![1.5, 3.5]);
//! ```
//!
//! **1D Example with multidimensional data**
//! ``` rust
//! use ndarray_interp::interp2d::*;
//! use ndarray::*;
//!
//! let data = array![
//! // ---------------------------------> y
//! [[1.0, -1.0], [2.0, -2.0], [3.0, -3.0]], // |
//! [[4.0, -4.0], [5.0, -5.0], [6.0, -6.0]], // |
//! [[7.0, -7.0], [8.0, -8.0], [9.0, -9.0]], // V
//! [[7.5, -7.5], [8.5, -8.5], [9.5, -9.5]], // x
//! ];
//! let x = array![1.0, 2.0, 3.0, 4.0];
//! let y = array![1.0, 2.0, 3.0];
//!
//! let interp = Interp2D::builder(data)
//! .x(x)
//! .y(y)
//! .build().unwrap();
//!
//! let result = interp.interp(1.5, 2.0).unwrap();
//! assert!(result == array![3.5, -3.5]);
//! let result = interp.interp_array(&array![1.5, 1.5], &array![2.0, 2.5]).unwrap();
//! assert!(result == array![[3.5, -3.5],[4.0, -4.0]]);
//! ```
use ManuallyDrop;
use Error;
/// Errors during Interpolator creation
/// Errors during Interpolation
/// cast `a` from type `A` to type `B` without any safety checks
///
/// ## Safety
/// - The caller must guarantee that `A` and `B` are the same types
/// - Types should be annotated to ensure type inference does not break
/// the contract by accident
unsafe