GriddedData

Struct GriddedData 

Source
pub struct GriddedData<const N: usize> { /* private fields */ }
Expand description

This struct contains the N-dimensional grid data and provides interpolation methods which work on this data.

§Features

This struct can be serialized / deserialized if the serde feature is enabled. See the docstring of the serde_impl module.

Implementations§

Source§

impl<const N: usize> GriddedData<N>

Source

pub fn new(axes: [Vec<f64>; N], data: Vec<f64>) -> Result<Self, Error>

Creates a new n-dimensional GriddedData with the number of dimensions defined by the input.

If the arguments are valid, this function creates a new instance of GriddedData with the number of dimension equal to the length of axes. The given arguments must fulfil the following criteria:

  • Each vector in the axes array must be strictly monotonic increasing
  • Each vector in the axes must have at least two values (if it doesn’t, the corresponding dimension collapses anyway and the vector can be omitted entirely).
  • The number of datapoints (data.len()) must be equal to the product of the lengths of the axis vectors within axes.

The data must be given in row-major fashion (index of last dimension changes fastest). Some examples:

  • The 2D-matrix

    1.0 3.0 5.0
    2.0 4.0 6.0

    is represented by data = [1.0, 3.0, 5.0, 2.0, 4.0, 6.0] (first dimension is the row number, second one the column number).

  • The 3D-matrix (| denotes a page / 3rd dimension separator)

    1.0 3.0 5.0 | 7.0  9.0 11.0
    2.0 4.0 6.0 | 8.0 10.0 12.0

    is represented by data = [1.0, 7.0, 3.0, 9.0, 5.0, 11.0, 2.0, 8.0, 4.0, 10.0, 6.0, 12.0] (first dimension is the row number, second one the column number, third one the page number).

§Examples
use gridded_data::GriddedData;

/*
2 x 3 x 3 matrix
  z = 1.0     z = 2.0
  y 3 4 6     3  4  6
x -------     -------
0 | 0 3 5     7  9 11
1 | 2 4 6     8 10 12
 */
let data = vec![1.0, 7.0, 3.0, 9.0, 5.0, 11.0, 2.0, 8.0, 4.0, 10.0, 6.0, 12.0];

let x = vec![0.0, 1.0];
let y = vec![3.0, 4.0, 6.0]; // Spacing does not need to be uniform!
let z = vec![1.0, 2.0];
assert!(GriddedData::new([x, y, z], data).is_ok());

If the data is available in matrix form, consider using the CartesianIndices iterator from the cart_lin library (which is a dependency of this library):

use cart_lin::CartesianIndices;
use gridded_data::GriddedData;

// 2 x 2 matrix
// 1.0 3.0
// 2.0 4.0
let matrix = [[1.0, 3.0], [2.0, 4.0]];
let mut data = Vec::with_capacity(4);
for idx in CartesianIndices::new([2, 2]) {
    data.push(matrix[idx[0]][idx[1]]);
}
let x = vec![0.0, 1.0];
let y = vec![1.0, 2.0];
assert_eq!(data, vec![1.0, 3.0, 2.0, 4.0]);
assert!(GriddedData::new([x, y], data).is_ok());

As an alternative for two-dimensional data, consider using GriddedData::from_slice_of_slices.

Source

pub fn axes(&self) -> &[Vec<f64>; N]

Access the raw data of the underlying axes.

Source

pub fn data(&self) -> &[f64]

Access the raw underlying data.

Source

pub fn data_mut(&mut self) -> &mut [f64]

Access the raw underlying data mutably.

Source

pub fn get_cart(&self, indices: &[usize; N]) -> Option<&f64>

Access the raw underlying data via cartesian indices.

This function uses cart_to_lin from the cart_lin crate to convert the given cartesian indices into a linear index and use that to access GriddedData::data. If the given cartesian index would result in an out-of bounds access, None is returned instead.

Source

pub fn get_cart_mut(&mut self, indices: &[usize; N]) -> Option<&mut f64>

Access the raw underlying data mutably via cartesian indices.

This function uses cart_to_lin from the cart_lin crate to convert the given cartesian indices into a linear index and use that to access GriddedData::data_mut. If the given cartesian index would result in an out-of bounds access, None is returned instead.

Source

pub unsafe fn get_cart_unchecked(&self, indices: &[usize; N]) -> &f64

Like GriddedData::get_cart, but does not perform any bound checking and is therefore unsafe.

Source

pub unsafe fn get_cart_unchecked_mut( &mut self, indices: &[usize; N], ) -> &mut f64

Like GriddedData::get_cart_mut, but does not perform any bound checking and is therefore unsafe.

Source

pub fn axes_len(&self) -> [usize; N]

Returns the lengths of all axes.

Source

pub fn get_lin(&self, index: usize) -> Option<&f64>

Access the raw underlying data via a linear index.

This is a convenience wrapper around self.data().get().

Source

pub fn get_lin_mut(&mut self, index: usize) -> Option<&mut f64>

Access the raw underlying data mutably via a linear index.

This is a convenience wrapper around self.get_mut().get().

Source

pub unsafe fn get_lin_unchecked(&self, index: usize) -> &f64

Like GriddedData::get_lin, but does not perform bounds checking and is therefore unsafe.

Source

pub unsafe fn get_lin_unchecked_mut(&mut self, index: usize) -> &mut f64

Like GriddedData::get_lin_mut, but does not perform bounds checking and is therefore unsafe.

Source

pub fn axes_values_cart(&self, indices: &[usize; N]) -> Option<[f64; N]>

Returns the axes values which correspond to the given cartesian index.

use gridded_data::GriddedData;

let grid = GriddedData::new([vec![0.0, 1.0], vec![1.0, 2.0]], vec![1.0, 3.0, 2.0, 4.0]).expect("valid inputs");
assert_eq!(grid.axes_values_cart(&[1, 0]).expect("valid index"), [1.0, 1.0]);
Source

pub unsafe fn axes_values_cart_unchecked( &self, indices: &[usize; N], ) -> [f64; N]

Like GriddedData::axes_values_cart, but does not perform bounds checking and is therefore unsafe.

Source

pub fn cell_bounds(&self, point: &[f64; N]) -> Option<[[usize; 2]; N]>

Returns the cell / hypercuboid bounds containing the given point.

If the given point is within the grid, this function finds the indices of the node interval of each axis which contain the corresponding point value. Please see the top-level documentation for a discussion of the underlying concept.

§Examples
use gridded_data::GriddedData;

let data = vec![1.0, 7.0, 3.0, 9.0, 5.0, 11.0, 2.0, 8.0, 4.0, 10.0, 6.0, 12.0];
let x = vec![0.0, 1.0];
let y = vec![3.0, 4.0, 6.0]; // Spacing does not need to be uniform!
let z = vec![1.0, 2.0];
let grid = GriddedData::new([x, y, z], data).expect("valid input");

/*
The x-coordinate of the given point is between the 0th and the 1st node
of the x-axis, the y-coordinate is between the 1st and the 2nd node and the
z-coordinate is between the 0th and the 1st node.
 */
assert_eq!(grid.cell_bounds(&[0.5, 4.1, 1.5]), Some([[0, 1], [1, 2], [0, 1]]));

/*
x-coordinate directly on 0th node
y-coordinate directly on 1st node -> Two different intervals could be returned:
[0, 1] or [1, 2]. This function returns the "right-side" interval
z-coordinate directly on 1st node
 */
assert_eq!(grid.cell_bounds(&[0.0, 4.0, 2.0]), Some([[0, 1], [1, 2], [0, 1]]));

// y-coordinate outside grid -> Return None.
assert_eq!(grid.cell_bounds(&[0.5, 6.1, 1.5]), None);
Source

pub fn contains(&self, point: &[f64; N]) -> bool

Returns whether the given point is inside the grid or not.

§Examples
use gridded_data::GriddedData;

let grid = GriddedData::new([vec![0.0, 1.0], vec![1.0, 2.0]], vec![1.0, 3.0, 2.0, 4.0]).expect("valid inputs");

assert!(grid.contains(&[0.5, 1.2]));
assert!(!grid.contains(&[1.5, 1.2]));
Source

pub fn nearest_neighbor_interp(&self, point: &[f64; N]) -> f64

Performs a nearest-neighbor interpolation for the given point.

This function first finds the “cell” (see GriddedData::cell_bounds) which contains the given point. Afterwards, it calculates the Euclidian distance of the point to each cell node and identifies the cartesian indices of the nearest node. Finally, it returns the corresponding data value.

In case the point is outside the grid, the only difference is that there is just one node per dimension for each point value outside of the respective axis.

§Examples
use gridded_data::GriddedData;

let data = vec![1.0, 7.0, 3.0, 9.0, 5.0, 11.0, 2.0, 8.0, 4.0, 10.0, 6.0, 12.0];
let x = vec![0.0, 1.0];
let y = vec![3.0, 4.0, 6.0]; // Spacing does not need to be uniform!
let z = vec![1.0, 2.0];
let grid = GriddedData::new([x, y, z], data).expect("valid input");

/*
This point is inside the cell with the bounds x = [0.0, 1.0], y = [4.0, 6.0], z = [1.0, 2.0]
Within this cell, it is closest to the node [1.0, 4.0, 2.0], which corresponds to the data value 10.0
 */
assert_eq!(grid.nearest_neighbor_interp(&[0.9, 4.2, 1.7]), 10.0);

/*
The x-coordinate of this point is outside the grid -> Extrapolation by only considering the x-node with value 0.0
 */
assert_eq!(grid.nearest_neighbor_interp(&[-1.0, 4.2, 1.7]), 9.0);
Source

pub fn linear_interp(&self, point: &[f64; N]) -> f64

Performs a multivariate linear interpolation for the given point.

This function performs a generalized bilinear interpolation and calculates the return value as

output = num / denom

with

num = [ P11..11 * (a2-a) * (b2-b) * ... (n2-n) + P21..11 * (a-a1) * (b2-b) * ... (n2-n) + ... + P22..22 * (a-a1) * (b-b1) * ... (n-n1) ]
denom = [ (a2-a1) * (b2-b1) * ... (n2-n1) ]
  • 1 is the index of the smaller value, 2 is the index of the larger value
  • P11..11 to P22..22 are the node values of the multidimensional grid
  • a1, a2 are the two data values along the first axis, b1, b2 along the second axis and so on.
  • a, b, …, n are the values of the input point for the corresponding dimensions.

If the point is outside the grid, a nearest-neighbor extrapolation is performed instead.

§Examples
use gridded_data::GriddedData;

let data = vec![1.0, 7.0, 3.0, 9.0, 5.0, 11.0, 2.0, 8.0, 4.0, 10.0, 6.0, 12.0];
let x = vec![0.0, 1.0];
let y = vec![3.0, 4.0, 6.0]; // Spacing does not need to be uniform!
let z = vec![1.0, 2.0];
let grid = GriddedData::new([x, y, z], data).expect("valid input");

// Values within the grid (tolerance accounts for limited floating-point accuracy)
assert!((grid.linear_interp(&[0.9, 4.2, 1.7]) - 8.3).abs() < 1e-10);
assert!((grid.linear_interp(&[0.8, 3.7, 1.2]) - 4.4).abs() < 1e-10);

// Value outside grid -> Nearest-neighbor extrapolation
assert_eq!(grid.linear_interp(&[-1.0, 4.2, 1.7]), 9.0);
Source§

impl GriddedData<2>

Source

pub fn from_slice_of_slices( axes: [Vec<f64>; 2], data: &[&[f64]], ) -> Result<Self, Error>

Create a 2-dimensional GriddedData using a slices-of-slices matrix as data.

§Examples
use gridded_data::GriddedData;

let row1 = [1.0, 3.0];
let row2 = [2.0, 4.0];
let data = [row1.as_slice(), row2.as_slice()];
let grid = GriddedData::from_slice_of_slices([vec![0.0, 1.0], vec![1.0, 2.0]], data.as_slice()).expect("valid inputs");
assert_eq!(grid.data(), &[1.0, 2.0, 3.0, 4.0]);
Source

pub fn from_nalgebra_matrix<R: Dim, C: Dim, S: RawStorage<f64, R, C>>( axes: [Vec<f64>; 2], matrix: &Matrix<f64, R, C, S>, ) -> Result<Self, Error>

Create a 2-dimensional GriddedData using a nalgebra matrix.

§Examples
use gridded_data::GriddedData;
use nalgebra::Matrix2;

let row1 = [1.0, 3.0];
let row2 = [2.0, 4.0];
let data = Matrix2::from_vec(vec![1.0, 3.0, 2.0, 4.0]); // nalgebra is column-major!
let grid = GriddedData::from_nalgebra_matrix([vec![0.0, 1.0], vec![1.0, 2.0]], &data).expect("valid inputs");
assert_eq!(grid.data(), &[1.0, 2.0, 3.0, 4.0]); // The data within grid is stored row-major.
§Features

Only available if the nalgebra feature is enabled.

Trait Implementations§

Source§

impl<const N: usize> Clone for GriddedData<N>

Source§

fn clone(&self) -> GriddedData<N>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<const N: usize> Debug for GriddedData<N>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<1>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<10>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<11>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<12>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<13>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<14>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<15>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<16>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<2>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<3>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<4>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<5>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<6>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<7>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<8>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<'de> Deserialize<'de> for GriddedData<9>

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<const N: usize> Index<&[usize; N]> for GriddedData<N>

Source§

type Output = f64

The returned type after indexing.
Source§

fn index(&self, index: &[usize; N]) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl<const N: usize> Index<usize> for GriddedData<N>

Source§

type Output = f64

The returned type after indexing.
Source§

fn index(&self, index: usize) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
Source§

impl<const N: usize> IndexMut<&[usize; N]> for GriddedData<N>

Source§

fn index_mut(&mut self, index: &[usize; N]) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
Source§

impl<const N: usize> IndexMut<usize> for GriddedData<N>

Source§

fn index_mut(&mut self, index: usize) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
Source§

impl Serialize for GriddedData<1>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<10>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<11>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<12>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<13>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<14>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<15>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<16>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<2>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<3>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<4>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<5>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<6>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<7>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<8>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Serialize for GriddedData<9>

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<const N: usize> Freeze for GriddedData<N>

§

impl<const N: usize> RefUnwindSafe for GriddedData<N>

§

impl<const N: usize> Send for GriddedData<N>

§

impl<const N: usize> Sync for GriddedData<N>

§

impl<const N: usize> Unpin for GriddedData<N>

§

impl<const N: usize> UnwindSafe for GriddedData<N>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,