-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor yield curve construction and handling
This commit streamlines yield curve handling by using the qlab-math crate to perform interpolation instead of the previously implemented linear interpolation contained within the qlab-termstructure crate. Consequently, this led to the deletion of `grid_point.rs` and `linear_interpolation.rs`. This refactoring simplifies the termstructure codebase, making it more reusable, and in aligning with best practices, it improves code modularity and maintainability.
- Loading branch information
1 parent
8e84308
commit 2d1ebfa
Showing
13 changed files
with
229 additions
and
146 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
use num_traits::Float; | ||
use qlab_error::ComputeError::InvalidInput; | ||
use qlab_error::QLabResult; | ||
|
||
pub mod linear; | ||
|
||
#[derive(Copy, Clone)] | ||
pub(crate) struct Point<V: Float> { | ||
x: V, | ||
y: V, | ||
} | ||
|
||
mod private { | ||
use crate::interpolation::Point; | ||
use num_traits::Float; | ||
|
||
pub(crate) trait InterpolatorInner<V: Float> { | ||
fn set_points(&mut self, points: &[Point<V>]); | ||
} | ||
} | ||
|
||
#[allow(private_bounds)] | ||
pub trait Interpolator<V: Float>: private::InterpolatorInner<V> { | ||
/// Fits the given data points to the `QLab` object. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `xs` - An array slice containing the x-values of the data points. | ||
/// * `ys` - An array slice containing the y-values of the data points. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Returns an `Err` variant if the lengths of `xs` and `ys` do not match. | ||
fn fit(&mut self, xs: &[V], ys: &[V]) -> QLabResult<()> { | ||
if xs.len() != ys.len() { | ||
return Err(InvalidInput( | ||
format!( | ||
"The length `xs`: {} must coincide with that of `ys`: {}", | ||
xs.len(), | ||
ys.len() | ||
) | ||
.into(), | ||
) | ||
.into()); | ||
} | ||
let mut points = Vec::with_capacity(xs.len()); | ||
for (&x, &y) in xs.iter().zip(ys) { | ||
points.push(Point { x, y }); | ||
} | ||
self.set_points(points.as_ref()); | ||
Ok(()) | ||
} | ||
|
||
/// Returns the value of type `V` and wraps it in a `QLabResult`. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `t` - The value of type `V`. | ||
/// | ||
/// # Returns | ||
/// | ||
/// Returns a `QLabResult` that contains the value `t`. | ||
/// | ||
/// # Errors | ||
/// | ||
/// An Error returns if interpolation fails. | ||
fn value(&self, t: V) -> QLabResult<V>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use crate::interpolation::private::InterpolatorInner; | ||
use crate::interpolation::{Interpolator, Point}; | ||
use num_traits::Float; | ||
use qlab_error::ComputeError::InvalidInput; | ||
use qlab_error::QLabResult; | ||
use std::fmt::Debug; | ||
|
||
#[derive(Default)] | ||
pub struct Linear<V: Float> { | ||
points: Vec<Point<V>>, | ||
} | ||
|
||
impl<V: Float> Linear<V> { | ||
#[must_use] | ||
pub fn new() -> Self { | ||
Self { points: Vec::new() } | ||
} | ||
} | ||
|
||
impl<V: Float + Debug> InterpolatorInner<V> for Linear<V> { | ||
fn set_points(&mut self, points: &[Point<V>]) { | ||
self.points = points.to_vec(); | ||
} | ||
} | ||
|
||
impl<V: Float + Debug> Interpolator<V> for Linear<V> { | ||
/// Calculates the value at time `t` using linear interpolation based on a grid of points. | ||
/// If `t` is greater than or equal to the x-coordinate of the last grid point, the y-coordinate of the last grid point will be returned. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `t` - The time value at which to calculate the interpolated value. | ||
/// | ||
/// # Returns | ||
/// | ||
/// * `QLabResult<V>` - The interpolated value at time `t`. | ||
/// - If `t` is smaller than the x-coordinate of the first grid point, an `InvalidInput` error will be returned. | ||
/// - If there are no grid points available, an `InvalidInput` error will be returned. | ||
/// | ||
/// # Errors | ||
/// | ||
/// * `InvalidInput` - Represents an error when the input is invalid or out-of-bounds. | ||
fn value(&self, t: V) -> QLabResult<V> { | ||
let last_point = self | ||
.points | ||
.last() | ||
.ok_or(InvalidInput("Grid points doesn't exist".into()))?; | ||
|
||
if t >= last_point.x { | ||
return Ok(last_point.y); | ||
} | ||
let idx = self.points.partition_point(|&point| point.x < t); | ||
if idx == 0 { | ||
return Err(InvalidInput( | ||
format!("t: {t:?} is smaller than the `x` value of the first grid point").into(), | ||
) | ||
.into()); | ||
} | ||
|
||
Ok(self.points[idx - 1].y | ||
+ (self.points[idx].y - self.points[idx - 1].y) | ||
/ (self.points[idx].x - self.points[idx - 1].x) | ||
* (t - self.points[idx - 1].x)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.