mirror of
https://github.com/Magnus167/rustframe.git
synced 2025-08-20 20:19:59 +00:00
Compare commits
33 Commits
9be85c9bad
...
1c4833aa80
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1c4833aa80 | ||
e2db5eb315 | |||
aeaf936380 | |||
![]() |
3f24764a13 | ||
![]() |
25a2a0d831 | ||
![]() |
1dbe5d0efe | ||
![]() |
b17863dcdc | ||
![]() |
ac0eed2d56 | ||
![]() |
73a30d45c5 | ||
![]() |
3cb68be062 | ||
![]() |
ca734fbedf | ||
![]() |
36a0846efa | ||
![]() |
7f587a7b7e | ||
![]() |
a30a7101e8 | ||
![]() |
10c6116f8f | ||
![]() |
ecb1939ec2 | ||
![]() |
bdd0a23096 | ||
![]() |
4c02006153 | ||
![]() |
9fd3582061 | ||
![]() |
8574d86abc | ||
![]() |
20727a2b91 | ||
bdef7f1732 | |||
34cff9f05e | |||
![]() |
f91ddc5c41 | ||
![]() |
ba1e2b3d43 | ||
![]() |
a0a551c7d9 | ||
![]() |
7cf41171a8 | ||
![]() |
38c5c28454 | ||
![]() |
3c8b69d3ab | ||
2b4ef8a371 | |||
![]() |
1213d588ec | ||
![]() |
a76963ec2e | ||
![]() |
caaf8c9411 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,5 +12,6 @@ data/
|
|||||||
*.info
|
*.info
|
||||||
|
|
||||||
.venv/
|
.venv/
|
||||||
|
.vscode/
|
||||||
|
|
||||||
tarpaulin-report.*
|
tarpaulin-report.*
|
21
README.md
21
README.md
@ -76,17 +76,26 @@ let total: f64 = result.sum_vertical().iter().sum::<f64>();
|
|||||||
assert_eq!(total, 184.0);
|
assert_eq!(total, 184.0);
|
||||||
|
|
||||||
// broadcast & reduce
|
// broadcast & reduce
|
||||||
let result: Matrix<f64> = &ma + 1.0; // add scalar
|
let result: Matrix<f64> = ma.clone() + 1.0; // add scalar
|
||||||
let result: Matrix<f64> = &result - 1.0; // subtract scalar
|
let result: Matrix<f64> = result + &ma - &ma; // add matrix
|
||||||
let result: Matrix<f64> = &result * 2.0; // multiply by scalar
|
let result: Matrix<f64> = result - 1.0; // subtract scalar
|
||||||
let result: Matrix<f64> = &result / 2.0; // divide by scalar
|
let result: Matrix<f64> = result * 2.0; // multiply by scalar
|
||||||
|
let result: Matrix<f64> = result / 2.0; // divide by scalar
|
||||||
|
|
||||||
let check: bool = result.eq_elementwise(ma.clone()).all();
|
let check: bool = result.eq_elem(ma.clone()).all();
|
||||||
assert!(check);
|
assert!(check);
|
||||||
|
|
||||||
// The above math can also be written as:
|
// The above math can also be written as:
|
||||||
let check: bool = (&(&(&(&ma + 1.0) - 1.0) * 2.0) / 2.0)
|
let check: bool = (&(&(&(&ma + 1.0) - 1.0) * 2.0) / 2.0)
|
||||||
.eq_elementwise(ma)
|
.eq_elem(ma.clone())
|
||||||
.all();
|
.all();
|
||||||
assert!(check);
|
assert!(check);
|
||||||
|
|
||||||
|
// The above math can also be written as:
|
||||||
|
let check: bool = ((((ma.clone() + 1.0) - 1.0) * 2.0) / 2.0)
|
||||||
|
.eq_elem(ma)
|
||||||
|
.all();
|
||||||
|
assert!(check);
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -96,9 +96,10 @@ impl BoolOps for Frame<bool> {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::frame::*;
|
use super::*;
|
||||||
use crate::matrix::*;
|
use crate::matrix::Matrix;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_series_ops() {
|
fn test_series_ops() {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -648,8 +648,13 @@ fn collect_monthly(
|
|||||||
let mut year = start_date.year();
|
let mut year = start_date.year();
|
||||||
let mut month = start_date.month();
|
let mut month = start_date.month();
|
||||||
|
|
||||||
let next_month =
|
let next_month = |(yr, mo): (i32, u32)| -> (i32, u32) {
|
||||||
|(yr, mo): (i32, u32)| -> (i32, u32) { if mo == 12 { (yr + 1, 1) } else { (yr, mo + 1) } };
|
if mo == 12 {
|
||||||
|
(yr + 1, 1)
|
||||||
|
} else {
|
||||||
|
(yr, mo + 1)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let candidate = if want_first_day {
|
let candidate = if want_first_day {
|
||||||
@ -873,6 +878,25 @@ fn last_day_of_year(year: i32) -> Result<NaiveDate, Box<dyn Error>> {
|
|||||||
|
|
||||||
// --- Generator Helper Functions ---
|
// --- Generator Helper Functions ---
|
||||||
|
|
||||||
|
fn get_first_date_helper(freq: DateFreq) -> fn(i32, u32) -> Result<NaiveDate, Box<dyn Error>> {
|
||||||
|
if matches!(
|
||||||
|
freq,
|
||||||
|
DateFreq::Daily | DateFreq::WeeklyMonday | DateFreq::WeeklyFriday
|
||||||
|
) {
|
||||||
|
panic!("Daily, WeeklyMonday, and WeeklyFriday frequencies are not supported here");
|
||||||
|
}
|
||||||
|
|
||||||
|
match freq {
|
||||||
|
DateFreq::MonthStart => first_day_of_month,
|
||||||
|
DateFreq::MonthEnd => last_day_of_month,
|
||||||
|
DateFreq::QuarterStart => first_day_of_quarter,
|
||||||
|
DateFreq::QuarterEnd => last_day_of_quarter,
|
||||||
|
DateFreq::YearStart => |year, _| first_day_of_year(year),
|
||||||
|
DateFreq::YearEnd => |year, _| last_day_of_year(year),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Finds the *first* valid date according to the frequency,
|
/// Finds the *first* valid date according to the frequency,
|
||||||
/// starting the search *on or after* the given `start_date`.
|
/// starting the search *on or after* the given `start_date`.
|
||||||
fn find_first_date_on_or_after(
|
fn find_first_date_on_or_after(
|
||||||
@ -883,69 +907,42 @@ fn find_first_date_on_or_after(
|
|||||||
DateFreq::Daily => Ok(start_date), // The first daily date is the start date itself
|
DateFreq::Daily => Ok(start_date), // The first daily date is the start date itself
|
||||||
DateFreq::WeeklyMonday => move_to_day_of_week_on_or_after(start_date, Weekday::Mon),
|
DateFreq::WeeklyMonday => move_to_day_of_week_on_or_after(start_date, Weekday::Mon),
|
||||||
DateFreq::WeeklyFriday => move_to_day_of_week_on_or_after(start_date, Weekday::Fri),
|
DateFreq::WeeklyFriday => move_to_day_of_week_on_or_after(start_date, Weekday::Fri),
|
||||||
DateFreq::MonthStart => {
|
|
||||||
let mut candidate = first_day_of_month(start_date.year(), start_date.month())?;
|
DateFreq::MonthStart | DateFreq::MonthEnd => {
|
||||||
|
// let mut candidate = first_day_of_month(start_date.year(), start_date.month())?;
|
||||||
|
let get_cand_func = get_first_date_helper(freq);
|
||||||
|
let mut candidate = get_cand_func(start_date.year(), start_date.month())?;
|
||||||
if candidate < start_date {
|
if candidate < start_date {
|
||||||
let (next_y, next_m) = if start_date.month() == 12 {
|
let (next_y, next_m) = if start_date.month() == 12 {
|
||||||
(start_date.year().checked_add(1).ok_or("Year overflow")?, 1)
|
(start_date.year().checked_add(1).ok_or("Year overflow")?, 1)
|
||||||
} else {
|
} else {
|
||||||
(start_date.year(), start_date.month() + 1)
|
(start_date.year(), start_date.month() + 1)
|
||||||
};
|
};
|
||||||
candidate = first_day_of_month(next_y, next_m)?;
|
candidate = get_cand_func(next_y, next_m)?;
|
||||||
}
|
}
|
||||||
Ok(candidate)
|
Ok(candidate)
|
||||||
}
|
}
|
||||||
DateFreq::MonthEnd => {
|
DateFreq::QuarterStart | DateFreq::QuarterEnd => {
|
||||||
let mut candidate = last_day_of_month(start_date.year(), start_date.month())?;
|
|
||||||
if candidate < start_date {
|
|
||||||
let (next_y, next_m) = if start_date.month() == 12 {
|
|
||||||
(start_date.year().checked_add(1).ok_or("Year overflow")?, 1)
|
|
||||||
} else {
|
|
||||||
(start_date.year(), start_date.month() + 1)
|
|
||||||
};
|
|
||||||
candidate = last_day_of_month(next_y, next_m)?;
|
|
||||||
}
|
|
||||||
Ok(candidate)
|
|
||||||
}
|
|
||||||
DateFreq::QuarterStart => {
|
|
||||||
let current_q = month_to_quarter(start_date.month());
|
let current_q = month_to_quarter(start_date.month());
|
||||||
let mut candidate = first_day_of_quarter(start_date.year(), current_q)?;
|
let get_cand_func = get_first_date_helper(freq);
|
||||||
|
let mut candidate = get_cand_func(start_date.year(), current_q)?;
|
||||||
if candidate < start_date {
|
if candidate < start_date {
|
||||||
let (next_y, next_q) = if current_q == 4 {
|
let (next_y, next_q) = if current_q == 4 {
|
||||||
(start_date.year().checked_add(1).ok_or("Year overflow")?, 1)
|
(start_date.year().checked_add(1).ok_or("Year overflow")?, 1)
|
||||||
} else {
|
} else {
|
||||||
(start_date.year(), current_q + 1)
|
(start_date.year(), current_q + 1)
|
||||||
};
|
};
|
||||||
candidate = first_day_of_quarter(next_y, next_q)?;
|
candidate = get_cand_func(next_y, next_q)?;
|
||||||
}
|
}
|
||||||
Ok(candidate)
|
Ok(candidate)
|
||||||
}
|
}
|
||||||
DateFreq::QuarterEnd => {
|
|
||||||
let current_q = month_to_quarter(start_date.month());
|
DateFreq::YearStart | DateFreq::YearEnd => {
|
||||||
let mut candidate = last_day_of_quarter(start_date.year(), current_q)?;
|
let get_cand_func = get_first_date_helper(freq);
|
||||||
if candidate < start_date {
|
let mut candidate = get_cand_func(start_date.year(), 0)?;
|
||||||
let (next_y, next_q) = if current_q == 4 {
|
|
||||||
(start_date.year().checked_add(1).ok_or("Year overflow")?, 1)
|
|
||||||
} else {
|
|
||||||
(start_date.year(), current_q + 1)
|
|
||||||
};
|
|
||||||
candidate = last_day_of_quarter(next_y, next_q)?;
|
|
||||||
}
|
|
||||||
Ok(candidate)
|
|
||||||
}
|
|
||||||
DateFreq::YearStart => {
|
|
||||||
let mut candidate = first_day_of_year(start_date.year())?;
|
|
||||||
if candidate < start_date {
|
if candidate < start_date {
|
||||||
candidate =
|
candidate =
|
||||||
first_day_of_year(start_date.year().checked_add(1).ok_or("Year overflow")?)?;
|
get_cand_func(start_date.year().checked_add(1).ok_or("Year overflow")?, 0)?;
|
||||||
}
|
|
||||||
Ok(candidate)
|
|
||||||
}
|
|
||||||
DateFreq::YearEnd => {
|
|
||||||
let mut candidate = last_day_of_year(start_date.year())?;
|
|
||||||
if candidate < start_date {
|
|
||||||
candidate =
|
|
||||||
last_day_of_year(start_date.year().checked_add(1).ok_or("Year overflow")?)?;
|
|
||||||
}
|
}
|
||||||
Ok(candidate)
|
Ok(candidate)
|
||||||
}
|
}
|
||||||
@ -962,7 +959,8 @@ fn find_next_date(current_date: NaiveDate, freq: DateFreq) -> Result<NaiveDate,
|
|||||||
DateFreq::WeeklyMonday | DateFreq::WeeklyFriday => current_date
|
DateFreq::WeeklyMonday | DateFreq::WeeklyFriday => current_date
|
||||||
.checked_add_signed(Duration::days(7))
|
.checked_add_signed(Duration::days(7))
|
||||||
.ok_or_else(|| "Date overflow adding 7 days".into()),
|
.ok_or_else(|| "Date overflow adding 7 days".into()),
|
||||||
DateFreq::MonthStart => {
|
DateFreq::MonthStart | DateFreq::MonthEnd => {
|
||||||
|
let get_cand_func = get_first_date_helper(freq);
|
||||||
let (next_y, next_m) = if current_date.month() == 12 {
|
let (next_y, next_m) = if current_date.month() == 12 {
|
||||||
(
|
(
|
||||||
current_date.year().checked_add(1).ok_or("Year overflow")?,
|
current_date.year().checked_add(1).ok_or("Year overflow")?,
|
||||||
@ -971,21 +969,11 @@ fn find_next_date(current_date: NaiveDate, freq: DateFreq) -> Result<NaiveDate,
|
|||||||
} else {
|
} else {
|
||||||
(current_date.year(), current_date.month() + 1)
|
(current_date.year(), current_date.month() + 1)
|
||||||
};
|
};
|
||||||
first_day_of_month(next_y, next_m)
|
get_cand_func(next_y, next_m)
|
||||||
}
|
}
|
||||||
DateFreq::MonthEnd => {
|
DateFreq::QuarterStart | DateFreq::QuarterEnd => {
|
||||||
let (next_y, next_m) = if current_date.month() == 12 {
|
|
||||||
(
|
|
||||||
current_date.year().checked_add(1).ok_or("Year overflow")?,
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(current_date.year(), current_date.month() + 1)
|
|
||||||
};
|
|
||||||
last_day_of_month(next_y, next_m)
|
|
||||||
}
|
|
||||||
DateFreq::QuarterStart => {
|
|
||||||
let current_q = month_to_quarter(current_date.month());
|
let current_q = month_to_quarter(current_date.month());
|
||||||
|
let get_cand_func = get_first_date_helper(freq);
|
||||||
let (next_y, next_q) = if current_q == 4 {
|
let (next_y, next_q) = if current_q == 4 {
|
||||||
(
|
(
|
||||||
current_date.year().checked_add(1).ok_or("Year overflow")?,
|
current_date.year().checked_add(1).ok_or("Year overflow")?,
|
||||||
@ -994,25 +982,14 @@ fn find_next_date(current_date: NaiveDate, freq: DateFreq) -> Result<NaiveDate,
|
|||||||
} else {
|
} else {
|
||||||
(current_date.year(), current_q + 1)
|
(current_date.year(), current_q + 1)
|
||||||
};
|
};
|
||||||
first_day_of_quarter(next_y, next_q)
|
get_cand_func(next_y, next_q)
|
||||||
}
|
}
|
||||||
DateFreq::QuarterEnd => {
|
DateFreq::YearStart | DateFreq::YearEnd => {
|
||||||
let current_q = month_to_quarter(current_date.month());
|
let get_cand_func = get_first_date_helper(freq);
|
||||||
let (next_y, next_q) = if current_q == 4 {
|
get_cand_func(
|
||||||
(
|
current_date.year().checked_add(1).ok_or("Year overflow")?,
|
||||||
current_date.year().checked_add(1).ok_or("Year overflow")?,
|
0,
|
||||||
1,
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(current_date.year(), current_q + 1)
|
|
||||||
};
|
|
||||||
last_day_of_quarter(next_y, next_q)
|
|
||||||
}
|
|
||||||
DateFreq::YearStart => {
|
|
||||||
first_day_of_year(current_date.year().checked_add(1).ok_or("Year overflow")?)
|
|
||||||
}
|
|
||||||
DateFreq::YearEnd => {
|
|
||||||
last_day_of_year(current_date.year().checked_add(1).ok_or("Year overflow")?)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
6
src/utils/dateutils/mod.rs
Normal file
6
src/utils/dateutils/mod.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
pub mod bdates;
|
||||||
|
pub use bdates::{BDateFreq, BDatesList, BDatesGenerator};
|
||||||
|
|
||||||
|
pub mod dates;
|
||||||
|
pub use dates::{DateFreq, DatesList, DatesGenerator};
|
||||||
|
|
@ -1,6 +1,3 @@
|
|||||||
pub mod bdates;
|
pub mod dateutils;
|
||||||
pub use bdates::{BDateFreq, BDatesList, BDatesGenerator};
|
pub use dateutils::{BDateFreq, BDatesGenerator, BDatesList};
|
||||||
|
pub use dateutils::{DateFreq, DatesGenerator, DatesList};
|
||||||
pub mod dates;
|
|
||||||
pub use dates::{DateFreq, DatesList, DatesGenerator};
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user