Skip to content

Commit

Permalink
feat: add norm (#266)
Browse files Browse the repository at this point in the history
This PR adds `norm` operator.

## Pull Request type

<!-- Please try to limit your pull request to one type; submit multiple
pull requests if needed. -->

Please check the type of change your PR introduces:

- [ ] Bugfix
- [x] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no API changes)
- [ ] Build-related changes
- [ ] Documentation content changes
- [ ] Other (please describe):

## What is the current behavior?

<!-- Please describe the current behavior that you are modifying, or
link to a relevant issue. -->

Issue Number: N/A

## What is the new behavior?

<!-- Please describe the behavior or changes that are being added by
this PR. -->

- calculating Norm of a given list.
- all tests are passed.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!-- If this does introduce a breaking change, please describe the
impact and migration path for existing applications below. -->

## Other information

<!-- Any other information that is important to this PR, such as
screenshots of how the component looks before and after the change. -->

---------

Co-authored-by: Lucas @ StarkWare <70894690+LucasLvy@users.noreply.github.com>
  • Loading branch information
Soptq and 0xLucqs authored Jan 26, 2024
1 parent 24cdc62 commit 5e5c2dd
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ dependencies = [
[[package]]
name = "alexandria_linalg"
version = "0.1.0"
dependencies = [
"alexandria_math",
]

[[package]]
name = "alexandria_math"
Expand Down
4 changes: 4 additions & 0 deletions src/linalg/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Linear Algebra

## [Norm](./src/norm.cairo)

Calculate the norm of an u128 array ([see also](https://numpy.org/doc/stable/reference/generated/numpy.linalg.norm.html)).

## [Dot product](./src/dot.cairo)

The dot product or scalar product is an algebraic operation that takes two equal-length sequences of numbers (usually coordinate vectors), and returns a single number. Algebraically, the dot product is the sum of the products of the corresponding entries of the two sequences of numbers ([see also](https://en.wikipedia.org/wiki/Dot_product)).
Expand Down
3 changes: 3 additions & 0 deletions src/linalg/Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ homepage = "https://github.com/keep-starknet-strange/alexandria/tree/main/src/li

[tool]
fmt.workspace = true

[dependencies]
alexandria_math = { path = "../math" }
1 change: 1 addition & 0 deletions src/linalg/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod dot;
mod kron;
mod norm;

#[cfg(test)]
mod tests;
36 changes: 36 additions & 0 deletions src/linalg/src/norm.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//! Norm of an T array.
use alexandria_math::fast_root::fast_nr_optimize;
use alexandria_math::pow;

/// Compute the norm for an T array.
/// # Arguments
/// * `array` - The inputted array.
/// * `ord` - The order of the norm.
/// * `iter` - The number of iterations to run the algorithm
/// # Returns
/// * `u128` - The norm for the array.
fn norm<T, +Into<T, u128>, +Zeroable<T>, +Copy<T>>(
mut xs: Span<T>, ord: u128, iter: usize
) -> u128 {
let mut norm: u128 = 0;
loop {
match xs.pop_front() {
Option::Some(x_value) => {
if ord == 0 {
if (*x_value).is_non_zero() {
norm += 1;
}
} else {
norm += pow((*x_value).into(), ord);
}
},
Option::None => { break; },
};
};

if ord == 0 {
return norm;
}

fast_nr_optimize(norm, ord, iter)
}
1 change: 1 addition & 0 deletions src/linalg/src/tests.cairo
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mod dot_test;
mod kron_test;
mod norm_test;
29 changes: 29 additions & 0 deletions src/linalg/src/tests/norm_test.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use alexandria_linalg::norm::norm;

#[test]
#[available_gas(2000000)]
fn norm_test_1() {
let mut array: Array<u128> = array![3, 4];
assert(norm(array.span(), 2, 10) == 5, 'invalid l2 norm');
}

#[test]
#[available_gas(2000000)]
fn norm_test_2() {
let mut array: Array<u128> = array![3, 4];
assert(norm(array.span(), 1, 10) == 7, 'invalid l1 norm');
}

#[test]
#[available_gas(2000000)]
fn norm_test_3() {
let mut array: Array<u128> = array![3, 4];
assert(norm(array.span(), 0, 10) == 2, 'invalid l1 norm');
}

#[test]
#[available_gas(2000000)]
fn norm_test_into() {
let mut array: Array<u32> = array![3, 4];
assert(norm(array.span(), 2, 10) == 5, 'invalid l2 norm');
}

0 comments on commit 5e5c2dd

Please sign in to comment.