diff --git a/src/conversions/binary_to_hexadecimal.rs b/src/conversions/binary_to_hexadecimal.rs new file mode 100644 index 00000000000..704e00f9153 --- /dev/null +++ b/src/conversions/binary_to_hexadecimal.rs @@ -0,0 +1,102 @@ +// Author : cyrixninja +// Binary to Hex Converter : Converts Binary to Hexadecimal +// Wikipedia References : 1. https://en.wikipedia.org/wiki/Hexadecimal +// 2. https://en.wikipedia.org/wiki/Binary_number + +static BITS_TO_HEX: &[(u8, &str)] = &[ + (0b0000, "0"), + (0b0001, "1"), + (0b0010, "2"), + (0b0011, "3"), + (0b0100, "4"), + (0b0101, "5"), + (0b0110, "6"), + (0b0111, "7"), + (0b1000, "8"), + (0b1001, "9"), + (0b1010, "a"), + (0b1011, "b"), + (0b1100, "c"), + (0b1101, "d"), + (0b1110, "e"), + (0b1111, "f"), +]; + +fn bin_to_hexadecimal(binary_str: &str) -> String { + let binary_str = binary_str.trim(); + + if binary_str.is_empty() { + return String::from("Invalid Input"); + } + + let is_negative = binary_str.starts_with('-'); + let binary_str = if is_negative { + &binary_str[1..] + } else { + binary_str + }; + + if !binary_str.chars().all(|c| c == '0' || c == '1') { + return String::from("Invalid Input"); + } + + let padded_len = (4 - (binary_str.len() % 4)) % 4; + let binary_str = format!("{:0width$}", binary_str, width = binary_str.len() + padded_len); + + // Convert binary to hexadecimal + let mut hexadecimal = String::with_capacity(binary_str.len() / 4 + 2); + hexadecimal.push_str("0x"); + + for chunk in binary_str.as_bytes().chunks(4) { + let mut nibble = 0; + for (i, &byte) in chunk.iter().enumerate() { + nibble |= ((byte - b'0') as u8) << (3 - i); + } + + let hex_char = BITS_TO_HEX + .iter() + .find(|&&(bits, _)| bits == nibble) + .map(|&(_, hex)| hex) + .unwrap(); + hexadecimal.push_str(hex_char); + } + + if is_negative { + format!("-{}", hexadecimal) + } else { + hexadecimal + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_empty_string() { + let input = ""; + let expected = "Invalid Input"; + assert_eq!(bin_to_hexadecimal(input), expected); + } + + #[test] + fn test_invalid_binary() { + let input = "a"; + let expected = "Invalid Input"; + assert_eq!(bin_to_hexadecimal(input), expected); + } + + #[test] + fn test_binary() { + let input = "00110110"; + let expected = "0x36"; + assert_eq!(bin_to_hexadecimal(input), expected); + } + + #[test] + fn test_padded_binary() { + let input = " 1010 "; + let expected = "0xa"; + assert_eq!(bin_to_hexadecimal(input), expected); + } +} diff --git a/src/machine_learning/loss_function/mae_loss.rs b/src/machine_learning/loss_function/mae_loss.rs new file mode 100644 index 00000000000..b2a6e286d59 --- /dev/null +++ b/src/machine_learning/loss_function/mae_loss.rs @@ -0,0 +1,36 @@ +//! # Mean Absolute Error Loss Function +//! +//! The `mae_loss` function calculates the Mean Absolute Error loss, which is a +//! robust loss function used in machine learning. +//! +//! ## Formula +//! +//! For a pair of actual and predicted values, represented as vectors `actual` +//! and `predicted`, the Mean Absolute loss is calculated as: +//! +//! - loss = `(actual - predicted) / n_elements`. +//! +//! It returns the average loss by dividing the `total_loss` by total no. of +//! elements. +//! +pub fn mae_loss(predicted: &Vec, actual: &[f64]) -> f64 { + let mut total_loss: f64 = 0.0; + for (p, a) in predicted.iter().zip(actual.iter()) { + let diff: f64 = p - a; + let absolute_diff: f64 = diff.abs(); + total_loss += absolute_diff; + } + total_loss / (predicted.len() as f64) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_mae_loss() { + let predicted_values: Vec = vec![1.0, 2.0, 3.0, 4.0]; + let actual_values: Vec = vec![1.0, 3.0, 3.5, 4.5]; + assert_eq!(mae_loss(&predicted_values, &actual_values), 0.5); + } +} diff --git a/src/machine_learning/loss_function/mod.rs b/src/machine_learning/loss_function/mod.rs index 840a8f5350d..8a46a9a3811 100644 --- a/src/machine_learning/loss_function/mod.rs +++ b/src/machine_learning/loss_function/mod.rs @@ -1,3 +1,5 @@ +mod mae_loss; mod mse_loss; +pub use self::mae_loss::mae_loss; pub use self::mse_loss::mse_loss; diff --git a/src/machine_learning/mod.rs b/src/machine_learning/mod.rs index 6d91c831989..27efc7b9cb5 100644 --- a/src/machine_learning/mod.rs +++ b/src/machine_learning/mod.rs @@ -3,5 +3,8 @@ mod loss_function; mod optimization; pub use self::linear_regression::linear_regression; + +pub use self::loss_function::mae_loss; pub use self::loss_function::mse_loss; + pub use self::optimization::gradient_descent;