/ nalgebra Public

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.

# Matrix macro#886

Merged
merged 25 commits into from
May 9, 2021
Merged

# Matrix macro #886

merged 25 commits into from
May 9, 2021

## Conversation

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

### Andlon commented May 3, 2021 • edited Loading

This PR introduces four new macros to `nalgebra`. They are available under the (now default) `macros` feature, which makes `nalgebra` export the macros from the procedural macro crate `nalgebra-macros`. The macros are:

• `matrix![]` for constructing fixed-size matrices with a MATLAB-like syntax.
• `dmatrix![]` for constructing dynamic matrices with the same syntax as `matrix!`
• `vector![]` for constructing small fixed-size vectors (syntax basically the same as `vec!`)
• `dvector![]` for constructing dynamically allocated vectors with the same syntax as `vector`.

The intention here is to simplify matrix/vector construction by improving readability, ease-of-use and ensuring that the matrix construction is as fast as possible.

Example:

```use nalgebra::matrix;

// Directly constructs an SMatrix<_, 2, 3>
let a = matrix![1, 2, 3;
4, 5, 6];```

Benefits over e.g. `MatrixRxC::new` constructors:

• Number of rows and columns are inferred from the data, so that when changing the data (e.g. increasing column count) you don't need to update both the data and the type.
• More succinct and obvious.
• Can be combined with e.g. `#[rustfmt::skip::macros(matrix)]` to prevent `rustfmt` from messing up carefully aligned syntax.
• Works for matrices of any (practical) size, not just those that have `new` constructors.
• Semi-colons clearly delineate where each row begins.

• Using the macros adds `syn` and `quote` to the dependency tree. On my 6-7 year old laptop, this adds ~10 secs to clean build compile time. Note that if you use `serde` or possibly some of the other optional dependencies, you might already have `syn`/`quote` in your dependency tree, so you pay effectively no penalty. If users don't need the macro, it's also possible to opt out by disabling the `macros` feature.
• I can't think of any others, but please let me know if I've missed any.

The user guide should probably be updated to accommodate these macros. My suggestion is to make these macros the de-facto way of constructing matrices with `nalgebra`.

Resolves #873.

added 19 commits May 3, 2021 13:52
``` Initial hacked together prototype without syn ```
``` e976922 ```
``` Initial impl using syn and quote ```
``` ab95cf7 ```
``` Fix warnings, refactor code ```
``` ed83350 ```
``` Exhaustive tests for small dimensions ```
``` 1dccdb1 ```
``` Update nalgebra-macros to nalgebra 0.26 and const generics ```
``` e60136f ```
``` Construct ArrayStorage directly in matrix![] ```
``` ec2a5a3 ```
``` Test that matrix![] can be used with const ```
``` 7098a4f ```
``` Implement SMatrix::from_array_storage and use it in matriX! impl ```
``` 9142dc8 ```
```This allows us to avoid injecting unsafe code into every macro
invocation, which seems desirable.```
``` Impl DMatrix/DVector::from_vec_storage ```
``` d2c11ad ```
```These methods enable safe & const construction of DMatrix/DVector from a
given VecStorage.```
``` Implement dmatrix![] macro ```
``` 5c84302 ```
``` Assert type in matrix/dmatrix tests ```
``` d56db1a ```
``` vector! and dvector! macros ```
``` 07d41e4 ```
``` Add trybuild tests to test error message reported when matrix dims mi… ```
``` da07749 ```
`…smatch`
``` Document macros ```
``` b96c755 ```
``` Add nalgebra/macros feature and re-export matrix macros from nalgebra ```
``` eeab4db ```
``` Document that feature needs to be enabled, and require macros feature… ```
``` 0bde07f ```
`… for tests`
``` Add macro sanity tests to macros ```
``` 041b8c4 ```
``` Test nalgebra-macros on CI ```
``` 08a77dd ```
``` Cargo fmt ```
``` 8552fc8 ```
commented
Show resolved Hide resolved

### Andlon commented May 4, 2021

 I'm missing one or more tests that verify that the macros work for all built-in types. I will add this as soon as I have time.

### Andlon commented May 4, 2021

 I'm also missing tests where instead of just numbers, we have arbitrary Rust expressions (though one of the doc tests has something like this). I will add this later too.

marked this pull request as draft May 4, 2021 09:25

### Ralith commented May 4, 2021

 What's the case for `vector![1, 2, 3]` existing as a distinct thing from `matrix![1; 2; 3]`?

### Andlon commented May 5, 2021

 What's the case for `vector![1, 2, 3]` existing as a distinct thing from `matrix![1; 2; 3]`? Semantics, mostly. Although a vector is also a matrix, matrices and vectors often play different roles in applications, so at least in my opinion it benefits readability to distinguish them at the syntax level (although you can indeed use `matrix!` to construct vectors as well, if you are so inclined). Second, `dvector![1, 2, 3]` and `dmatrix![1; 2; 3]` do not produce the same type. In the first case, you get `DVector`, in the second case `DMatrix`. It seems to me that for symmetry purposes it is then natural to have `vector!` mirror `dvector!` and `matrix!` mirror `dmatrix!`.

added 4 commits May 5, 2021 08:51
``` Improve nalgebra-macros/Cargo.toml metadata ```
``` f42ecf0 ```
``` Add tests to ensure macros compile for all built-in types ```
``` 57541aa ```
``` Test that matrix macros work with arbitrary expressions ```
``` 6026a05 ```
``` Formatting ```
``` 39b275f ```
marked this pull request as ready for review May 5, 2021 08:25

### Andlon commented May 5, 2021

 All right, I finished up the things I wanted to address, so I suppose this PR should be ready now.

### sebcrozet commented May 5, 2021 • edited Loading

 Hey @Andlon, this is an amazing PR. Thank you! I will review this within the next few days. The user guide should probably be updated to accommodate these macros. My suggestion is to make these macros the de-facto way of constructing matrices with nalgebra. I agree. I will take care of this later this month.

### Andlon commented May 5, 2021

 Thanks, @sebcrozet! I also wanted to add that I don't have much experience with proc macros, so if there's any experienced proc macro person with some good suggestions for improvement I'd also be happy to hear about that.

mentioned this pull request May 5, 2021
requested changes

### sebcrozet left a comment

Thank you again for this PR. This looks great. I'm not a proc-macro expert myself so I can't really judge the quality of the implementation. But it looks OK to me.

src/base/array_storage.rs Outdated Show resolved Hide resolved
src/base/vec_storage.rs Outdated Show resolved Hide resolved

### Ralith commented May 6, 2021

 The proc macro stuff LGTM.

added 2 commits May 7, 2021 09:00
``` Move from_{}_storage impl blocks to matrix.rs ```
``` 3a3bc55 ```
``` Enable from_{}_storage only when std/alloc available ```
``` 922393b ```

### Andlon commented May 7, 2021

 @sebcrozet: I moved the impl blocks, but I needed to add some conditional compilation for the `VecStorage`-related stuff in `matrix.rs`. Not sure if this is the way you prefer it. Let me know if you want it done differently. @Ralith: thanks for taking a look!

approved these changes

### sebcrozet commented May 9, 2021

 @Andlon Looks greatk thanks!

merged commit `23ac85e` into dimforge:dev May 9, 2021
deleted the matrix-macro branch May 10, 2021 21:30
mentioned this pull request Jun 2, 2021
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.

3 participants