Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Semiring Applications - All pairs shortest path (Tropical semiring) + Ridge Linear Regression (Semiring) #1221

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
24b8d90
part 1
chaeyeonlee07 May 2, 2024
ac7d0a0
editted semiring and added test
chaeyeonlee07 May 13, 2024
bdca8ca
editted semiring and added test
chaeyeonlee07 May 13, 2024
d791360
testing if this passes test
chaeyeonlee07 May 16, 2024
b36b83d
edit1
chaeyeonlee07 May 16, 2024
d68810f
fixed lint errors by adding allow dead code
chaeyeonlee07 May 17, 2024
8f89582
local lint test was passing but it wasn't ongithub so fixed
chaeyeonlee07 May 17, 2024
77514e5
fixed lib rs to fit the standard structure of lattice
chaeyeonlee07 May 17, 2024
b871d6e
changed lib rs so that semiring functions matches the structure of la…
chaeyeonlee07 May 17, 2024
8c838d7
test(semiring applications): added semiring applications and their co…
chaeyeonlee07 May 17, 2024
ab6b69e
Merge branch 'main' into semiring_application
chaeyeonlee07 May 17, 2024
86cb3a8
feat(semiring_applications): added all pair shortest path (APSP) algo…
chaeyeonlee07 May 22, 2024
5ac169f
feat(semiring_applications): added APSP (all pairs shortest path) alg…
chaeyeonlee07 May 22, 2024
581bb32
feat(semiring_applications): changed the format of all-pairs-shortest…
chaeyeonlee07 May 28, 2024
2e517b0
feat: added ridge regression implementation and its corresponding tests.
chaeyeonlee07 Jun 6, 2024
e104619
feat(group_application): added zset group aggregation example
chaeyeonlee07 Jun 10, 2024
51b025d
feat(group_application): zset examples and their test.
chaeyeonlee07 Jun 10, 2024
a072b38
added new tests for apsp and commented out ridge regression tests
Sep 13, 2024
4767006
feat(semiring application): fixed apsp to take in a list of tuples in…
Sep 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions lattices/src/group_application.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
//! Module containing the [`Zset`] applications of groups.
use std::collections::HashMap;

use crate::{Addition, Inverse, Zero};

#[derive(PartialEq, Debug)]
/// Implementation of the Zset group (Z_A, +, 0, -Z_A) where A is the set of integers.

pub struct Zset(i32);

impl Zset {
/// Create a new instance of Zset with the given value.
pub fn new(value: i32) -> Self {
Zset(value)
}
}

/// Implementation of the addition trait for Zset group.
impl Addition<i32> for Zset {
/// Integer addition is add function of Zset.
fn add(&mut self, other: Zset) {
self.0 += other.0
}
}

/// Implementation of Identity for addition.
impl Zero<i32> for Zset {
/// 0 is the zero element of the semiring.
fn zero(&self) -> Zset {
Zset(0)
}
}

/// Implementation of Inverse for Zset group.
impl Inverse<i32> for Zset {
/// Returns the inverse of the group element.
fn inverse(&self) -> Zset {
Zset(-self.0)
}
}

#[allow(dead_code)]
/// Type alias for Zset map where keys are of type K and values are Zsets.
type ZsetMap<K> = HashMap<K, Zset>;

#[allow(dead_code)]
/// Type alias for indexed Zsets.
type IndexedZset<K, V> = HashMap<K, ZsetMap<V>>;

#[allow(dead_code)]
/// Flatmap function that converts an indexed Z-set into a Z-set of key-value pairs.
fn flatmap<K, V>(indexed_zset: IndexedZset<K, V>) -> ZsetMap<(K, V)>
where
K: Clone + Eq + std::hash::Hash,
V: Clone + Eq + std::hash::Hash,
{
let mut result: ZsetMap<(K, V)> = HashMap::new();

for (key, zset_map) in indexed_zset.into_iter() {
for (sub_key, zset) in zset_map.into_iter() {
let combined_key = (key.clone(), sub_key);
result
.entry(combined_key)
.or_insert_with(|| Zset(0))
.add(zset);
}
}

result
}

#[allow(dead_code)]
/// Group sum function that combines grouping and summation using flatmap.
fn group_sum<K, V, F>(input: ZsetMap<V>, f: F) -> ZsetMap<K>
where
K: Clone + Eq + std::hash::Hash,
V: Clone + Eq + std::hash::Hash,
F: Fn(&V) -> K,
{
let mut indexed_zset: IndexedZset<K, V> = HashMap::new();

// Grouping
for (value, zset) in input.into_iter() {
let key = f(&value);
indexed_zset.entry(key).or_default().insert(value, zset);
}

// Flattening and summing
let flat_zset = flatmap(indexed_zset);

// Aggregating the flattened Z-set by summing values for each group
let mut result: ZsetMap<K> = HashMap::new();
for ((key, _), zset) in flat_zset.into_iter() {
result.entry(key).or_insert_with(|| Zset(0)).add(zset);
}

result
}
#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_group_sum() {
// Create a ZsetMap with some initial values
let mut zset_map: ZsetMap<String> = HashMap::new();
zset_map.insert("joe".to_string(), Zset::new(1));
zset_map.insert("anne".to_string(), Zset::new(-1));
zset_map.insert("alice".to_string(), Zset::new(2));
zset_map.insert("john".to_string(), Zset::new(1));
zset_map.insert("jack".to_string(), Zset::new(3));

// Define a key function: extracts first character in the name variable.
let key_fn = |_name: &String| _name.chars().next().unwrap();

// Perform group sum operation
let grouped_sums = group_sum(zset_map, key_fn);

let mut expected: ZsetMap<char> = HashMap::new();
expected.insert('j', Zset::new(5)); // joe (1) + john (1) + jack (3)
expected.insert('a', Zset::new(1)); // anne (-1) + alice (2)

assert_eq!(grouped_sums, expected);
}

#[test]
fn test_group_sum_empty() {
// Create an empty ZsetMap
let zset_map: ZsetMap<String> = HashMap::new();

// Define a key function: extracts first character in the name variable.
let key_fn = |name: &String| name.chars().next().unwrap();

let grouped_sums = group_sum(zset_map, key_fn);

let expected: ZsetMap<char> = HashMap::new();

assert_eq!(grouped_sums, expected);
}

#[test]
fn test_group_sum_single_group() {
// Create a ZsetMap with values that all map to the same group
let mut zset_map: ZsetMap<String> = HashMap::new();
zset_map.insert("joe".to_string(), Zset::new(1));
zset_map.insert("john".to_string(), Zset::new(2));
zset_map.insert("jack".to_string(), Zset::new(3));

// Define a key function
let key_fn = |_name: &String| 'j'; // All keys will map to 'j'

let grouped_sums = group_sum(zset_map, key_fn);

let mut expected: ZsetMap<char> = HashMap::new();
expected.insert('j', Zset::new(6)); // joe (1) + john (2) + jack (3)

assert_eq!(grouped_sums, expected);
}

#[test]
fn test_group_sum_negative_values() {
// Create a ZsetMap with some negative values
let mut zset_map: ZsetMap<String> = HashMap::new();
zset_map.insert("joe".to_string(), Zset::new(-1));
zset_map.insert("anne".to_string(), Zset::new(-1));
zset_map.insert("alice".to_string(), Zset::new(1));
zset_map.insert("john".to_string(), Zset::new(-1));

// Define a key function: extracts first character in the name variable.
let key_fn = |name: &String| name.chars().next().unwrap();

let grouped_sums = group_sum(zset_map, key_fn);

let mut expected: ZsetMap<char> = HashMap::new();
expected.insert('j', Zset::new(-2)); // joe (-1) + john (-1)
expected.insert('a', Zset::new(0)); // anne (-1) + alice (1)

assert_eq!(grouped_sums, expected);
}
}
57 changes: 57 additions & 0 deletions lattices/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ pub mod algebra;
pub mod collections;
mod conflict;
mod dom_pair;
pub mod group_application;
pub mod map_union;
pub mod map_union_with_tombstones;
mod ord;
mod pair;
mod point;
pub mod semiring_application;
pub mod set_union;
pub mod set_union_with_tombstones;
pub mod test;
Expand All @@ -40,6 +42,61 @@ pub trait Lattice: Sized + Merge<Self> + LatticeOrd + NaiveLatticeOrd + IsBot +
#[sealed]
impl<T> Lattice for T where T: Sized + Merge<Self> + LatticeOrd + NaiveLatticeOrd + IsBot + IsTop {}

/// Alias trait for groups.
#[sealed]
pub trait Group<T>: Addition<T> + Zero<T> + Inverse<T> {}

/// Trait for Group Inverse.
pub trait Inverse<T> {
/// Returns the inverse of the group element.
fn inverse(&self) -> Self;
}

/// Alias trait for semirings.
#[sealed]
pub trait Semiring<T>: Addition<T> + Multiplication<T> + Zero<T> + One<T> {}

/// Trait for Semiring Addition.
pub trait Addition<Other> {
/// Add-assign `other` into self.
fn add(&mut self, other: Self);

/// Add `this` and `delta` together, returning the new value.
fn add_owned(mut self, other: Self) -> Self
where
Self: Sized,
{
self.add(other);
self
}
}

/// Trait for Semiring Multiplication.
pub trait Multiplication<Other> {
/// Multiply-assign `other` into self.
fn mul(&mut self, other: Self);

/// Multiply `this` and `delta` together, returning the new value.
fn mul_owned(mut self, other: Self) -> Self
where
Self: Sized,
{
self.mul(other);
self
}
}

/// Trait to check if semiring contains a zero.
pub trait Zero<T> {
/// Returns the zero element of the semiring. Identify for the Addition operation.
fn zero(&self) -> Self;
}

/// Trait to define a one in a semiring.
pub trait One<T> {
/// Returns the one element of the semiring. Identity for the multiplication operation.
fn one(&self) -> Self;
}
/// Trait for lattice merge (AKA "join" or "least upper bound").
pub trait Merge<Other> {
/// Merge `other` into the `self` lattice.
Expand Down
Loading
Loading