Compare commits

...

33 Commits

Author SHA1 Message Date
Palash Tyagi
1c4833aa80
Merge e2db5eb31535caa083f42cf13f7a88d15a2eff2a into aeaf93638050524c8251e0a6d3a2a6913753d1c8 2025-05-03 01:32:48 +01:00
e2db5eb315
Merge branch 'main' into date_utils 2025-05-03 01:32:47 +01:00
aeaf936380
Merge pull request #34 from Magnus167/update_matrix_implementation
Enhance matrix operations and error handling
2025-05-03 01:30:07 +01:00
Palash Tyagi
3f24764a13 Merge branch 'main' into update_matrix_implementation 2025-05-03 01:22:28 +01:00
Palash Tyagi
25a2a0d831 Add .vscode/ to .gitignore to exclude Visual Studio Code settings 2025-05-03 01:19:27 +01:00
Palash Tyagi
1dbe5d0efe Update matrix arithmetic operations 2025-05-03 01:19:01 +01:00
Palash Tyagi
b17863dcdc Organize code structure by adding section comments 2025-05-03 01:18:24 +01:00
Palash Tyagi
ac0eed2d56 Add comprehensive arithmetic and boolean logic tests for Matrix operations 2025-05-03 01:17:01 +01:00
Palash Tyagi
73a30d45c5 Rename test matrix creation functions for clarity and consistency 2025-05-03 01:16:33 +01:00
Palash Tyagi
3cb68be062 Refactor element-wise arithmetic operations to use a centralized dimension check for improved error handling 2025-05-03 01:11:59 +01:00
Palash Tyagi
ca734fbedf Enhance bitwise operations for boolean matrices and implement logical NOT for both owned and borrowed matrices 2025-05-03 00:39:08 +01:00
Palash Tyagi
36a0846efa Enhance element-wise arithmetic operations for Matrix + Scalar to support in-place modifications and improve performance 2025-05-03 00:38:07 +01:00
Palash Tyagi
7f587a7b7e Enhance element-wise arithmetic operations for Matrix to support multiple ownership variants and improve in-place modifications 2025-05-03 00:37:06 +01:00
Palash Tyagi
a30a7101e8 Refactor element-wise comparison macro to improve naming consistency 2025-05-03 00:36:03 +01:00
Palash Tyagi
10c6116f8f Enhance element-wise comparison methods to optimize data handling 2025-05-03 00:35:34 +01:00
Palash Tyagi
ecb1939ec2 Enhance error messages in Broadcastable trait to clarify row and column count mismatches 2025-05-03 00:32:46 +01:00
Palash Tyagi
bdd0a23096 Enhance add_column and add_row methods to handle empty matrices and improve error handling 2025-05-03 00:31:11 +01:00
Palash Tyagi
4c02006153 Optimize column swapping logic to handle empty matrices and prevent unnecessary swaps 2025-05-03 00:29:14 +01:00
Palash Tyagi
9fd3582061 Refactor delete_row method to improve bounds checking and optimize data rebuilding 2025-05-03 00:26:43 +01:00
Palash Tyagi
8574d86abc Enhance delete_column method to improve efficiency of column removal 2025-05-03 00:26:21 +01:00
Palash Tyagi
20727a2b91 Improve column swapping logic to handle empty matrices and prevent overlapping swaps 2025-05-03 00:25:45 +01:00
bdef7f1732
Merge branch 'main' into date_utils 2025-05-02 23:38:53 +01:00
34cff9f05e
Merge branch 'main' into update_frame_init 2025-05-02 23:38:42 +01:00
Palash Tyagi
f91ddc5c41 Improve assertions and documentation for matrix operations; allow 0-row matrices from empty columns. 2025-05-01 23:56:06 +01:00
Palash Tyagi
ba1e2b3d43 update imports and module docstring 2025-05-01 23:14:37 +01:00
Palash Tyagi
a0a551c7d9 update into_vec, from_vec 2025-05-01 23:13:57 +01:00
Palash Tyagi
7cf41171a8 Allow creation of 0-row matrices from empty column data and improve data flattening in from_cols method. 2025-05-01 23:12:19 +01:00
Palash Tyagi
38c5c28454 Enhance matrix assertions for row and column operations to allow 0-row matrices with empty columns and improve error messages for index out of bounds. 2025-05-01 23:10:51 +01:00
Palash Tyagi
3c8b69d3ab Merge branch 'main' into update_frame_init 2025-05-01 01:09:21 +01:00
2b4ef8a371
Merge branch 'main' into date_utils 2025-05-01 01:03:32 +01:00
Palash Tyagi
1213d588ec Refactor date frequency handling in DatesList to improve clarity and reduce code duplication 2025-04-29 23:43:12 +01:00
Palash Tyagi
a76963ec2e move bdates and dates modules into dateutils module 2025-04-29 00:03:06 +01:00
Palash Tyagi
caaf8c9411 Refactor test module imports 2025-04-27 01:41:38 +01:00
8 changed files with 763 additions and 293 deletions

1
.gitignore vendored
View File

@ -12,5 +12,6 @@ data/
*.info
.venv/
.vscode/
tarpaulin-report.*

View File

@ -76,17 +76,26 @@ let total: f64 = result.sum_vertical().iter().sum::<f64>();
assert_eq!(total, 184.0);
// broadcast & reduce
let result: Matrix<f64> = &ma + 1.0; // add scalar
let result: Matrix<f64> = &result - 1.0; // subtract scalar
let result: Matrix<f64> = &result * 2.0; // multiply by scalar
let result: Matrix<f64> = &result / 2.0; // divide by scalar
let result: Matrix<f64> = ma.clone() + 1.0; // add scalar
let result: Matrix<f64> = result + &ma - &ma; // add matrix
let result: Matrix<f64> = result - 1.0; // subtract 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);
// The above math can also be written as:
let check: bool = (&(&(&(&ma + 1.0) - 1.0) * 2.0) / 2.0)
.eq_elementwise(ma)
.eq_elem(ma.clone())
.all();
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);
```

View File

@ -96,9 +96,10 @@ impl BoolOps for Frame<bool> {
// }
// }
#[cfg(test)]
mod tests {
use crate::frame::*;
use crate::matrix::*;
use super::*;
use crate::matrix::Matrix;
#[test]
fn test_series_ops() {

File diff suppressed because it is too large Load Diff

View File

@ -648,8 +648,13 @@ fn collect_monthly(
let mut year = start_date.year();
let mut month = start_date.month();
let next_month =
|(yr, mo): (i32, u32)| -> (i32, u32) { if mo == 12 { (yr + 1, 1) } else { (yr, mo + 1) } };
let next_month = |(yr, mo): (i32, u32)| -> (i32, u32) {
if mo == 12 {
(yr + 1, 1)
} else {
(yr, mo + 1)
}
};
loop {
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 ---
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,
/// starting the search *on or after* the given `start_date`.
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::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::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 {
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 = first_day_of_month(next_y, next_m)?;
candidate = get_cand_func(next_y, next_m)?;
}
Ok(candidate)
}
DateFreq::MonthEnd => {
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 => {
DateFreq::QuarterStart | DateFreq::QuarterEnd => {
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 {
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 = first_day_of_quarter(next_y, next_q)?;
candidate = get_cand_func(next_y, next_q)?;
}
Ok(candidate)
}
DateFreq::QuarterEnd => {
let current_q = month_to_quarter(start_date.month());
let mut candidate = last_day_of_quarter(start_date.year(), current_q)?;
if candidate < start_date {
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())?;
DateFreq::YearStart | DateFreq::YearEnd => {
let get_cand_func = get_first_date_helper(freq);
let mut candidate = get_cand_func(start_date.year(), 0)?;
if candidate < start_date {
candidate =
first_day_of_year(start_date.year().checked_add(1).ok_or("Year overflow")?)?;
}
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")?)?;
get_cand_func(start_date.year().checked_add(1).ok_or("Year overflow")?, 0)?;
}
Ok(candidate)
}
@ -962,7 +959,8 @@ fn find_next_date(current_date: NaiveDate, freq: DateFreq) -> Result<NaiveDate,
DateFreq::WeeklyMonday | DateFreq::WeeklyFriday => current_date
.checked_add_signed(Duration::days(7))
.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 {
(
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 {
(current_date.year(), current_date.month() + 1)
};
first_day_of_month(next_y, next_m)
get_cand_func(next_y, next_m)
}
DateFreq::MonthEnd => {
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 => {
DateFreq::QuarterStart | DateFreq::QuarterEnd => {
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 {
(
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 {
(current_date.year(), current_q + 1)
};
first_day_of_quarter(next_y, next_q)
get_cand_func(next_y, next_q)
}
DateFreq::QuarterEnd => {
let current_q = month_to_quarter(current_date.month());
let (next_y, next_q) = if current_q == 4 {
(
current_date.year().checked_add(1).ok_or("Year overflow")?,
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")?)
DateFreq::YearStart | DateFreq::YearEnd => {
let get_cand_func = get_first_date_helper(freq);
get_cand_func(
current_date.year().checked_add(1).ok_or("Year overflow")?,
0,
)
}
}
}

View File

@ -0,0 +1,6 @@
pub mod bdates;
pub use bdates::{BDateFreq, BDatesList, BDatesGenerator};
pub mod dates;
pub use dates::{DateFreq, DatesList, DatesGenerator};

View File

@ -1,6 +1,3 @@
pub mod bdates;
pub use bdates::{BDateFreq, BDatesList, BDatesGenerator};
pub mod dates;
pub use dates::{DateFreq, DatesList, DatesGenerator};
pub mod dateutils;
pub use dateutils::{BDateFreq, BDatesGenerator, BDatesList};
pub use dateutils::{DateFreq, DatesGenerator, DatesList};