Skip to content

Conversation

@forfudan
Copy link
Collaborator

@forfudan forfudan commented Jun 9, 2025

As title.

MadAlex1997 and others added 20 commits March 1, 2025 19:58
@shivasankarka @MadAlex1997, This is to pull the commits that were
directly made in `main` into `pre-0.7`.

No squash is needed.
This will:

1. Implemented `take_along_axis` function in
`numojo/routines/indexing.mojo`:
- Takes values from an input array along a specified axis based on
indices
   - Handles arrays of any dimension with axis specification
   - Supports broadcasting of indices when shapes don't exactly match
   - Includes proper error handling for invalid inputs

2. Created comprehensive test suite in
`tests/routines/test_indexing.mojo`:
   - Tests for arrays of different dimensions (1D, 2D, 3D)
   - Tests with various axis specifications (positive, negative indices)
   - Tests with different index types (int32, int64)
   - Verification against NumPy's implementation for correctness
Merge the commit on hotfix from main to pre-0.7

Co-authored-by: MadAlex1997 <[email protected]>
…e given axis (#230)

This pull request focuses on enhancing the functionality of the
`NDArray` class and improving the `argmax` and `argmin` methods.
Additionally, new tests have been added to ensure the correctness of
these methods.

Improvements to `argmax` and `argmin` methods:

* `numojo/routines/searching.mojo`: Introduced new `argmax` and `argmin`
functions that handle both 1D and multi-dimensional arrays. These
functions now support axis-based operations and include detailed
documentation and examples.
* `numojo/routines/functional.mojo`: Added overloads of
`apply_along_axis` to support the new `argmax` and `argmin` functions,
ensuring they reduce the dimension of the input array appropriately.

Enhancements to `NDArray` class:

* `numojo/core/ndarray.mojo`: The `argmax` and `argmin` methods have
been updated to use the new `searching.argmax` and `searching.argmin`
functions. These methods now return indices of the maximum and minimum
values along an axis, with improved documentation.

Bug fixes:

* `numojo/routines/math/extrema.mojo`: Corrected error messages in the
`max` and `min` functions to accurately reflect the function names.

New tests:

* `tests/routines/test_searching.mojo`: Added comprehensive tests for
the `argmax` and `argmin` functions, including tests for 1D, 2D, and 3D
arrays, as well as tests for negative axes and Fortran-order arrays.
Also included tests for `take_along_axis` with `argmax` and `argmin`.
### Summary

Previously, the distinction between `NDArray` and `ComplexNDArray` was
partially encoded through the use of `DType` and `CDType`. This PR
simplifies the type system by removing the custom `CDType` datatype and
replacing it with the standard `DType`. The use of `CDType` introduced
issues with Mojo's compile-time type conversions, resulting in
suboptimal user ergonomics and problems when converting between
datatypes. To address this, we are standardizing on `DType` moving
forward.

---

### New Syntax Proposal
To clearly differentiate between functions that create or manipulate
standard and complex arrays, we introduce a simple naming convention:
**append a `C` suffix** to functions returning complex arrays since Mojo
does not support function overloading based on return type. The
following is one such example,

```mojo
fn ones[dtype: DType = DType.float64](shape: NDArrayShape) raises -> NDArray[dtype]
    pass

fn onesC[dtype: DType = DType.float64](shape: NDArrayShape) raises -> ComplexNDArray[dtype]
    pass
```

This approach keeps the API intuitive, avoids return-type ambiguity, and
aligns better with Mojo's type system and simplifies a lot of type
conversions.
…r improved decomposition performance (#232)

**Summary**  
This PR makes the memory layout in the Matrix class configurable. In
addition to the default row-major (C-contiguous) layout, one can now use
column-major (F-contiguous) layout. This enhancement is especially
beneficial for routines such as QR decomposition. By aligning the data
layout with the typical access patterns, we can achieve better
performance when using SIMD.

Other Matrix libraries like
[Eigen](https://eigen.tuxfamily.org/dox/group__TopicStorageOrders.html)
allow compile-time selection of row-major or column-major storage
through C++ template parameters.

While Eigen handles this at compile time, the current approach does it
at runtime.

### Changes  

1. **Added a `order` Argument**  
- Modifies the `Matrix` constructor and static creation methods
(`zeros`, `ones`, `full`, `rand`, etc.) to accept an optional `order`
argument.
- When `order` is `C`, the matrix uses row-major (C-style). When `F`, it
uses column-major (F-style).

2. **Introduced `reorder_layout`**  
- A new function that creates a matrix with the opposite layout (C ↔ F)
and copies data over.
- Intended for use in algorithms that need to switch layout after an
operation or to prepare the matrix for certain column-based operations.

3. **Extended `Matrix.to_numpy`**  
- Respects the matrix’s memory layout. If `C_CONTIGUOUS` is set, data is
written in row-major; if `F_CONTIGUOUS` is set, data is written in
column-major.


### Future Work  

- **Compile-Time Parameter**: Adapting Matrix class to take a similar
approach to Eigen.
- **Adapt Decomposition Routines**: I have already implemented a QR
decomposition making use of the `F_CONTIGUOUS` memory layout. I will
make a follow-up PR.
…ut (#233)

This PR optimizes the QR decomposition utilizing configurable memory
layouts and SIMD. When the input matrix is detected to be in row-major
(C) layout, it is reordered to column-major (F) layout before performing
Householder transformations. After factorization, the final Q and R are
reordered to the original layout of the input Matrix, preserving
consistency for downstream operations. For an input matrix with
column-major (F) layout, no reordering is needed.

**Changes**  

1. **Vectorized Householder Transformations**  
Updated algorithm leverages SIMD with calls to `vectorize` for computing
and applying Householder reflections.

2. **Reduced and Complete Modes**  
Adds support for both “reduced” and “complete” modes, similar to NumPy’s
QR. For an input Matrix A with shape (m,n):
- “reduced”: Q has `shape(m, min(m,n))` and R has `shape(min(m,n), n)`.
     - “complete”: Q has `shape(m, m)` and R has `shape(m, n)`.  
3. **Additional tests**  
Beyond the existing test with `shape(20,20)` and default parameters, new
tests now verify the QR decomposition for non-square matrices
(`shape(12,5)` and `shape(5,12)`) in both reduced and complete modes.
…Matrix Routines (#234)

This PR enhances Matrix with support for both C-contiguous (row-major)
and F-contiguous (column-major) memory layouts across all matrix
routines. Default memory layout remains C-contiguous to keep API close
to NumPy. Matrix tests are performed for both memory layouts.

- Add conditional compilation flag `F_CONTIGUOUS` to control matrix
memory layout in tests
- Modify GitHub workflow to run test suite with both layouts:
- Additional test run for matrix tests with
[flag](https://docs.modular.com/mojo/cli/test/#-d-keyvalue) `-D
F_CONTIGUOUS`
- Matmul handles all memory layout combinations with specialized
implementations.
…Matrices (#238)

This PR adds eigenvalue decomposition for real symmetric matrices using
the QR algorithm.

- Added `eig()` function that returns a  A tuple `(Q, D)` where:
            - Q: A matrix whose columns are the eigenvectors
            - D: A diagonal matrix containing the eigenvalues
- Added `issymmetric()` helper function to verify matrix symmetry
This closes #239 that Zh-simplied document leads to a blank page.
This PR comments out all the Type Coercions for the data types that
currently implemented. This is done for the following two reasons,

- The current Mojo compiler isn't able to parse and calculate the
resulting data type at compile time correctly yet.
- The resulting generic data type is very confusing to work with for end
users currently and requires weird code shenanigans to work around it.

Therefore these will be temporarily commented out. We will get back to
improving it and adding it back in later version of NuMojo once Mojo
type system is mature enough for us to implement these data type
conversions at compile time.
# Error description
```mojo
fn main() raises:
    var list: List[Scalar[nm.f64]] = List[Scalar[nm.f64]]()
    for i in range(200):
        list.append(Scalar[nm.f64](1e-5))

    var array = nm.array[nm.f64](list).reshape(nm.Shape(200, 1))
    var den = nm.exp(-array) + 1.0
    var result = Scalar[nm.f64](1.0) / (den)
    print("r: ", r)
```
The above code produces an array filled with 2.0 which is wrong since
the expected result is an array filled with 0.5. This error occurred due
to the symmetric implementation of all arithmetic operators i.e `array
+-*/ scalar`, but this results in wrong value for division since it
always calculates `array / scalar` even when the user input is (scalar /
array).

# Solution
This PR fixes this error by adding a new function to the backends that
calculate the array and scalar arithmetic operations so that array /
scalar and scalar / array result in the correct values.
- Update the syntax to accommodate the changes in Mojo 25.3.
  - Changes in constructing of Python Objects.
  - Deprecation of `mut` keywords in `__init__`.
  - Deprecation of `format` methods for string literal.
  - Removal of unused variables.
  - Change string literal in the program into commenting lines.
  - etc.
- Update the `numpy` version to `>=2.0`.
- Update the channel priority.
This PR:

- Add stable sort to the function `sort()`. Users can use the argument
`stable` to make a stable sort.
- Re-write the in-place sort (instable and stable) using the
`apply_long_axis()` function, so that we do not need to several
transposes.
- Add an override for `apply_long_axis()`, which apply the function
in-place.
This PR brings new minor changes. 

- Switch from magic to pixi. Any command that involved the word 'magic'
should be replaced with 'pixi'.
- Replaced io backend ('load', 'save' etc) with numpy since it's a
dependancy already. More functions will be added in later updates. Added
basic test files for load and save.

---------

Co-authored-by: ZHU Yuhao 朱宇浩 <[email protected]>
@forfudan forfudan changed the base branch from main to arrayview June 10, 2025 12:13
@forfudan forfudan changed the base branch from arrayview to main June 10, 2025 12:13
forfudan added 2 commits June 10, 2025 14:20
…253)

There are conflicts between v0.6.1 (main) and the pre-0.7 branches. We
have to resolve them by first merging main to pre-0.7. This cannot be
done via a squash.

@shivasankarka, @MadAlex1997, please just approve it and not merge. I
will take of the merging.
@forfudan forfudan marked this pull request as ready for review June 10, 2025 13:02
@forfudan forfudan merged commit 2b72ef4 into main Jun 11, 2025
2 checks passed
@MadAlex1997 MadAlex1997 deleted the pre-0.7 branch July 1, 2025 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants