Users guide | Documentation | Forum
Linear algebra library for the Rust programming language.
Linear algebra library for Rust.
Home Page: https://nalgebra.org
License: Apache License 2.0
Users guide | Documentation | Forum
Linear algebra library for the Rust programming language.
Hello!
I am using glium as a dependency which in turn uses nalgebra and the build fails because of one of the macros. This happens on rust 1.0 stable.
ico@arch ted $ uname -a
Linux arch 4.0.2-1-ARCH #1 SMP PREEMPT Thu May 7 06:47:54 CEST 2015 x86_64 GNU/Linux
ico@arch ted $ multirust show-default
multirust: default toolchain: stable
multirust: default location: /home/ico/.multirust/toolchains/stable
rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)
cargo 0.2.0-nightly (efb482d 2015-04-30) (built 2015-04-30)
ico@arch ted $ cargo build
Compiling nalgebra v0.2.13
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295:22: 295:64 error: cannot transmute to or from a type that contains type parameters in its interior [E0139]
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295 &mem::transmute::<&$t<N>, [N; $dim * $dim]>(self)[i + j * $dim]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:288:1: 308:3 note: in expansion of index_impl!
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat.rs:63:1: 63:22 note: expansion site
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295:22: 295:64 error: cannot transmute to or from a type that contains type parameters in its interior [E0139]
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295 &mem::transmute::<&$t<N>, [N; $dim * $dim]>(self)[i + j * $dim]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:288:1: 308:3 note: in expansion of index_impl!
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat.rs:115:1: 115:22 note: expansion site
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295:22: 295:64 error: cannot transmute to or from a type that contains type parameters in its interior [E0139]
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295 &mem::transmute::<&$t<N>, [N; $dim * $dim]>(self)[i + j * $dim]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:288:1: 308:3 note: in expansion of index_impl!
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat.rs:200:1: 200:22 note: expansion site
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295:22: 295:64 error: cannot transmute to or from a type that contains type parameters in its interior [E0139]
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295 &mem::transmute::<&$t<N>, [N; $dim * $dim]>(self)[i + j * $dim]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:288:1: 308:3 note: in expansion of index_impl!
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat.rs:309:1: 309:22 note: expansion site
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295:22: 295:64 error: cannot transmute to or from a type that contains type parameters in its interior [E0139]
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295 &mem::transmute::<&$t<N>, [N; $dim * $dim]>(self)[i + j * $dim]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:288:1: 308:3 note: in expansion of index_impl!
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat.rs:436:1: 436:22 note: expansion site
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295:22: 295:64 error: cannot transmute to or from a type that contains type parameters in its interior [E0139]
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:295 &mem::transmute::<&$t<N>, [N; $dim * $dim]>(self)[i + j * $dim]
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat_macros.rs:288:1: 308:3 note: in expansion of index_impl!
/home/ico/.multirust/toolchains/beta/cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.2.13/src/structs/mat.rs:569:1: 569:22 note: expansion site
error: aborting due to 6 previous errors
Could not compile `nalgebra`.
To learn more, run the
Adding points makes the notion of affine space more explicit in nalgebra
.
This will change the behaviour of isometric transforms wrt. vectors:
Iso * Vec
rotates the vector.Iso * Pnt
rotates and translates the point.Also, this makes the behaviour of ToHomogeneous
more controlled:
na::to_homogeneous(vector)
returns Vec(vector.x, vector.y, ..., 0.0)
na::to_homogeneous(point)
returns Pnt(point.x, point.y, ..., 1.0)
Of course, one is still free to use Vec
as purly algebraic objects for multivariate calculus.
You really need to do this fast before your names are snapped up:
Currently you have to type na::Iso2::new(na::zero(), na::zero())
.
I believe it's missing some values but perhaps it is by design. I have laid out the entire problem here:
http://pastebin.com/GHSrUp61
src/traits/structure.rs:6:18: 6:22 error: unresolved import `std::slice::Iter`. There is no `Iter` in `std::slice`
src/traits/structure.rs:6 use std::slice::{Iter, IterMut};
^~~~
src/traits/structure.rs:6:24: 6:31 error: unresolved import `std::slice::IterMut`. There is no `IterMut` in `std::slice`
src/traits/structure.rs:6 use std::slice::{Iter, IterMut};
^~~~~~~
src/structs/mat.rs:7:18: 7:22 error: unresolved import `std::slice::Iter`. There is no `Iter` in `std::slice`
src/structs/mat.rs:7 use std::slice::{Iter, IterMut};
^~~~
src/structs/mat.rs:7:24: 7:31 error: unresolved import `std::slice::IterMut`. There is no `IterMut` in `std::slice`
src/structs/mat.rs:7 use std::slice::{Iter, IterMut};
^~~~~~~
src/structs/quat.rs:8:18: 8:22 error: unresolved import `std::slice::Iter`. There is no `Iter` in `std::slice`
src/structs/quat.rs:8 use std::slice::{Iter, IterMut};
^~~~
src/structs/quat.rs:8:24: 8:31 error: unresolved import `std::slice::IterMut`. There is no `IterMut` in `std::slice`
src/structs/quat.rs:8 use std::slice::{Iter, IterMut};
^~~~~~~
src/structs/vec.rs:6:18: 6:22 error: unresolved import `std::slice::Iter`. There is no `Iter` in `std::slice`
src/structs/vec.rs:6 use std::slice::{Iter, IterMut};
^~~~
src/structs/vec.rs:6:24: 6:31 error: unresolved import `std::slice::IterMut`. There is no `IterMut` in `std::slice`
src/structs/vec.rs:6 use std::slice::{Iter, IterMut};
^~~~~~~
src/structs/spec/vec0.rs:2:18: 2:22 error: unresolved import `std::slice::Iter`. There is no `Iter` in `std::slice`
src/structs/spec/vec0.rs:2 use std::slice::{Iter, IterMut};
^~~~
src/structs/spec/vec0.rs:2:24: 2:31 error: unresolved import `std::slice::IterMut`. There is no `IterMut` in `std::slice`
src/structs/spec/vec0.rs:2 use std::slice::{Iter, IterMut};
^~~~~~~
src/structs/pnt.rs:6:18: 6:22 error: unresolved import `std::slice::Iter`. There is no `Iter` in `std::slice`
src/structs/pnt.rs:6 use std::slice::{Iter, IterMut};
^~~~
src/structs/pnt.rs:6:24: 6:31 error: unresolved import `std::slice::IterMut`. There is no `IterMut` in `std::slice`
src/structs/pnt.rs:6 use std::slice::{Iter, IterMut};
^~~~~~~
src/structs/dvec.rs:7:18: 7:22 error: unresolved import `std::slice::Iter`. There is no `Iter` in `std::slice`
src/structs/dvec.rs:7 use std::slice::{Iter, IterMut};
^~~~
src/structs/dvec.rs:7:24: 7:31 error: unresolved import `std::slice::IterMut`. There is no `IterMut` in `std::slice`
src/structs/dvec.rs:7 use std::slice::{Iter, IterMut};
Projectors are a well-defined algeabric entities. Thus, they should be present in nalgebra, with a proper trait that allows projector-based genericity.
Convertion between projectors and homogeneous transformations will exist.
Is there an equivalent to cgmath's Matrix4::look_at
function?
fn look_at(eye: &Point3<S>, center: &Point3<S>, up: &Vector3<S>) -> Matrix4<S>
$ rustc --version
rustc 1.0.0-dev (built 2015-03-28)
$ cargo build
Compiling nalgebra v0.2.8 (file:///home/anders/rust/nalgebra)
src/structs/dmat.rs:167:19: 167:33 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dmat.rs:167 self.mij.as_mut_slice()
^~~~~~~~~~~~~~
src/structs/dmat.rs:167:33: 167:33 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dmat.rs:220:19: 220:33 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dmat.rs:220 *self.mij.as_mut_slice().get_unchecked_mut(offset) = val
^~~~~~~~~~~~~~
src/structs/dmat.rs:220:33: 220:33 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dmat.rs:252:18: 252:32 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dmat.rs:252 self.mij.as_mut_slice().swap(offset1, offset2);
^~~~~~~~~~~~~~
src/structs/dmat.rs:252:32: 252:32 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dmat.rs:285:22: 285:36 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dmat.rs:285 self.mij.as_mut_slice().get_unchecked_mut(offset)
^~~~~~~~~~~~~~
src/structs/dmat.rs:285:36: 285:36 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dmat.rs:410:30: 410:44 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dmat.rs:410 self.mij.as_mut_slice().swap(off_n0_j, off_k_j);
^~~~~~~~~~~~~~
src/structs/dmat.rs:410:44: 410:44 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dmat.rs:411:29: 411:43 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dmat.rs:411 res.mij.as_mut_slice().swap(off_n0_j, off_k_j);
^~~~~~~~~~~~~~
src/structs/dmat.rs:411:43: 411:43 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dmat.rs:485:30: 485:44 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dmat.rs:485 self.mij.as_mut_slice().swap(off_i_j, off_j_i);
^~~~~~~~~~~~~~
src/structs/dmat.rs:485:44: 485:44 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dvec_macros.rs:75:26: 75:40 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:40: 75:40 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dvec_macros.rs:75:26: 75:40 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:40: 75:40 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dvec_macros.rs:75:26: 75:40 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:40: 75:40 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dvec_macros.rs:75:26: 75:40 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:40: 75:40 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dvec_macros.rs:75:26: 75:40 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:40: 75:40 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dvec_macros.rs:75:26: 75:40 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:40: 75:40 help: add #![feature(collections)] to the crate attributes to enable
src/structs/dvec_macros.rs:75:26: 75:40 error: use of unstable library feature 'collections': use &mut s[..] instead
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:40: 75:40 help: add #![feature(collections)] to the crate attributes to enable
src/lib.rs:88:12: 88:16 warning: unused or unknown feature, #[warn(unused_features)] on by default
src/lib.rs:88 #![feature(test)]
^~~~
src/structs/dmat.rs:167:19: 167:33 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dmat.rs:167 self.mij.as_mut_slice()
^~~~~~~~~~~~~~
src/structs/dmat.rs:220:19: 220:33 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dmat.rs:220 *self.mij.as_mut_slice().get_unchecked_mut(offset) = val
^~~~~~~~~~~~~~
src/structs/dmat.rs:252:18: 252:32 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dmat.rs:252 self.mij.as_mut_slice().swap(offset1, offset2);
^~~~~~~~~~~~~~
src/structs/dmat.rs:285:22: 285:36 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dmat.rs:285 self.mij.as_mut_slice().get_unchecked_mut(offset)
^~~~~~~~~~~~~~
src/structs/dmat.rs:410:30: 410:44 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dmat.rs:410 self.mij.as_mut_slice().swap(off_n0_j, off_k_j);
^~~~~~~~~~~~~~
src/structs/dmat.rs:411:29: 411:43 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dmat.rs:411 res.mij.as_mut_slice().swap(off_n0_j, off_k_j);
^~~~~~~~~~~~~~
src/structs/dmat.rs:485:30: 485:44 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dmat.rs:485 self.mij.as_mut_slice().swap(off_i_j, off_j_i);
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:26: 75:40 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:26: 75:40 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:26: 75:40 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:26: 75:40 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:26: 75:40 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:26: 75:40 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
src/structs/dvec_macros.rs:75:26: 75:40 warning: use of deprecated item: use &mut s[..] instead, #[warn(deprecated)] on by default
src/structs/dvec_macros.rs:75 *self.at.as_mut_slice().get_unchecked_mut(i) = val
^~~~~~~~~~~~~~
error: aborting due to 14 previous errors
Could not compile `nalgebra`.
To learn more, run the command again with --verbose.
I just want to make sure that this is functioning as you intended it to.
With the following rust code
let persp: na::Mat4<f32> = na::PerspMat3::new(800.0 / 500.0, 45.0, 0.0001, 100.0).to_mat();
I get the following output:
-1.120369, 0, 0, 0
0, 1.792591, 0, 0
0, 0, 1.000002, -0.0002
0, 0, 1, 0
With the following glm code in c++
glm::mat4 proj = glm::perspective(45.0f, 800.0f / 500.0f, 0.0001f, 100.f);
I get the following:
1.120369, 0, 0, 0
0, 1.792591, 0, 0
0, 0, -1.000002, 0,
0, 0, -1, 0
The changes in sign cause my axis to be vertically inverted, such that (0, -1, 0) is up, but I would prefer that (0, 1, 0) be up. I'll gladly write my own perspective matrix function but I just wanted to make sure that this was intended on your end.
As far as I can see, currently you can write a generic function like this:
fn func<T>(u: Vec2<T>, v: Vec2<T>, a: T) -> Vec2<T>
where T: BaseFloat + Vec2MulRhs<T, Vec2<T>>
{
u * (a * a) + v * a
}
This is useful, when you want to write code that is dimension-specific but generic over the type of the scalar. This is a bit verbose and requires one to deal with the double-dispatch implementation details quite a bit.
As soon as where clauses are fully implemented, one can probably impose a trait bound like Vec2<T>: FloatVec<T>
. This is already much nicer and hides away the double dispatch.
There is still the issue though that imho T: BaseFloat
alone should imply Vec2<T>: FloatVec<T>
. This is an important property for writing code for which using a particular kind of vector is an implementation detail that should be hidden. With the current double-dispatch mechanics, this is a bit difficult but I think it's possible.
(Note: I edited this three times, because I incrementally realized that I had missed parts of the API invalidating my previous assertions about the current code base.)
Since rust-lang/rust#23606 has been merged now on the unstable branch, we can start experimenting with associated constants in this crate. This should most likely not be merged into the master branch right away, as it will only work on the nightlies. Also it will be a breaking change naturally.
Of course, this raises the question, how we want to deal with unstable features in general. Thoughts?
Looks like Mul
and Div
have changed their signatures.
Build fails on my system with the error that the trait core::ops::Neg is not implemented for the unsigned types (u8, u16, etc,...).
Removing the implementation of the BaseNum trait for these types seems to fix the problem, but I am not sure if this is the right way to fix the problem.
Using rustc 1.0.0-nightly (fed12499e 2015-03-03) (built 2015-03-04)
I am running into a bunch of run-time testing issues with the rand
module like this
thread 'test_transpose_mat6' panicked at 'arithmetic operation overflowed', /home/eduard/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.1.3/src/isaac.rs:316
Not sure, where exactly the problem occurs, but it might well be an upstream issue.
We are currently in the process of simplifying the numeric traits in the standard libraries (see rust-lang/rfcs#369). Perhaps we could move to algebra as a basis for nalgebra?
http://nalgebra.org/ is gorgeous. It is a shame not to have it more prominent. You can click 'edit' next to the repository description to add the website URL.
I see this: http://tomaka.github.io/glium/nalgebra/struct.Mat4.html#method.new_identity
But why does it take a dim: usize
argument? We already know it is 4x4.
@sebcrozet, afaik you are maintaining nalgebra on your own at the moment. Do you need help? With the current breaking changes in the compiler, nalgebra seems to require minor changes being merged and release to crates.io every couple days. Especially since people have started migrating over from cgmath, it would be good to respond to changes in the compiler quickly. I could offer some help in that regard if you want, as I am working with nalgebra almost all the time.
I cannot compile library cause of
unresolved name 'rand::random' in file src/structs/dvec.rs line 101 and in file src/structs/dmat.rs in line 78
I cloned rust today from mozilla/rust.
EDIT:
Seems that they have moved rand to std crate.
Also found error
binary operation '+' cannot be applied to type ´&'static str´ in file src/structs/spec/vec.rs lines 56, 65 and in file src/structs/spec/mat.rs lines 125, 147, 165, 168
We should be able to convert a, e.g., Mat4<f64>
to a [[f64, ..4], ..4]
.
Choosing a good epsilon for comparing floats is tricky. Floats close to 1.0 and floats way out there should probably be compared using quite different epsilons. Leaving that up to the library consumer is too much of a punt, IMHO.
I think it's more useful to specify the maximum allowable number of floating-point representations separating the two numbers being compared, otherwise known as ULPs (units in the last place, or units of least precision). IEEE754 data is stored so that when interpreted as 2-s complement integers, sort in the same order. So casting to integer, and subtracting, can give you the number of representations separating two floats.
I've used something like this (f32 example):
impl FloatApproxCmp<i32> for f32 {
fn ulps(self, rhs: f32) -> i32
{
// Setup integer representations of the input
let ai32: i32 = unsafe { mem::transmute(self) };
let bi32: i32 = unsafe { mem::transmute(rhs) };
ai32 - bi32
}
fn approx_cmp(self, rhs: f32, ulps: i32) -> i32
{
// Get exact equality out of the way.
// This nicely also handles -0 compared to +0
if self==rhs { return 0; }
// Handle differing signs as a special case, even if
// they are very close
if self>0_f32 && rhs<0_f32 { return 1; }
if self<0_f32 && rhs>0_f32 { return -1; }
let diff: i32 = self.ulps(rhs);
match diff {
x if x.abs() <= ulps => 0,
x if x < 0 => -1,
x if x > 0 => 1,
_ => 0
}
}
fn approx_eq(self, rhs: f32, ulps: i32) -> bool
{
let c :i32 = self.approx_cmp(rhs, ulps);
c==0
}
}
@aepsil0n
QuickCheck allows to test properties on arbitrary input. This prevents a larger class of bugs than example-based unit testing. My proposal is to use it for nalgebra's test suite. For convenience this involves implementing quickcheck::Arbitrary
for most types. These impls should be public (i.e. not only compiled for the test suite), so that user code can use these implementations to write own tests that involve nalgebra types.
We may think about making this an optional feature, as it adds a dependency to nalgebra.
btw, I volunteer to do this at some point, unless there are any objections.
TODO
quickcheck::Arbitrary
for all types.Now that breaking changes are mostly gone (I don't think you're using std::io, std::os, etc.), would it be possible to update the version of nalgebra on crates.io?
Pseudoinverse and singular value decomposition calculation, while difficult, is useful if nphysics (or some animation library) ever wants to implement Jacobian-based inverse kinematics methods. It's doable with just the transpose, but incredibly imprecise.
I already added this to cgmath
in rustgd/cgmath#131 and would like to contribute a similar feature here. The API differences are minor, so it should be mostly a matter of copy & paste. To make this self-consistent, I'll repeat the explanation:
Testing code with floating point numbers and nalgebra data structures one can use assertions on ApproxEq types:
assert!(approx_eq(&a, &b));
assert!(approx_eq_eps(&a, &b, &eps));
This does not yield readable error messages upon failure. Arguably it is also a bit ugly to read/write. I propose adding macros similar to assert_eq!
to alleviate this, e.g.:
assert_approx_eq!(a, b);
assert_approx_eq_eps!(a, b, eps);
The question is, whether exported macros should go in a separate crate or not. Since macros aren't namespaced some libraries do that, to allow importing macros separately from the rest of the functionality, while others don't. I don't think that would make a lot of sense here though, as the macro is tightly coupled to the ApproxEq trait.
Partially-dynamic matrices:
Sometimes when working with dynamic matrices I know e.g. the number of columns but not the number of rows before hand. This can be used to speedup lookup and slices by relying on a compile time constant for offsetting indices. This can also speed matrix slices since it allows to return stack allocated slices instead of dynamic vectors.
Dynamic matrices of bounded size:
Sometimes I know the maximum size a matrixis going to have, but not the exact size (it is still dynamic). This knowledge allows matrices to be stack allocated. Is the same argument as for the already implemented dynamic vectors of bounded size.
Mutable matrix slices:
Right now the matrix methods col_slice
and row_slice
return an immutable DVec<N>
. It would very useful to have a way to return a mutable slice to a matrix' sub-matrix (rows and cols are two common sub-matrices).
It would be nice to use SIMD for types that can support it. At the moment our SIMD support is pretty limited, but ASM is a possibility - perhaps with a fallback to regular operations.
There are some trait methods in nalgebra
that show a certain symmetry: one method takes &self
and returns a new object of the same type, while another takes &mut self
and turns the object itself into the same thing that the other function would have returned. Examples for this are Norm::normalize_cpy
and Norm::normalize
or Inv::inv_cpy
and Inv::inv
.
Now the issue that I see there is that normally Rust goes for immutability by default, whereas this naming scheme implies that the mutable version is the more common one. Using the mutable version should be a conscious choice. You are mutating state that semantically does not have to be mutable, so this is typically a performance or memory optimization of some sort.
Of course, this is a bit of bike-shedding, but I find a naming scheme such as Norm::normalize
/Norm::normalize_self
would imho be more appropriate.
An RFC that changes how you're allowed to lay out rust projects was just completed, and it basically completely breaks the build.
Here's what happens when I run make
with a recent rustc
:
$ make
mkdir -p lib
rustc src/lib.rs --out-dir lib --opt-level 3
src/structs/dmat.rs:16:5: 16:10 error: cannot declare a new module at this location
src/structs/dmat.rs:16 mod metal;
^~~~~
src/structs/dmat.rs:16:5: 16:10 note: maybe move this module `dmat` to its own directory via `dmat/mod.rs`
src/structs/dmat.rs:16 mod metal;
^~~~~
src/structs/dmat.rs:16:5: 16:10 note: ... or maybe `use` the module `metal` instead of possibly redeclaring it
src/structs/dmat.rs:16 mod metal;
^~~~~
error: aborting due to previous error
Makefile:5: recipe for target 'all' failed
make: *** [all] Error 101
This repeats for other files after switching to use
/ moving metal
- I don't completely understand how the project is laid out so I'm not sure how to fix it.
(Awesome library, by the way :)
Edit: whoops, there's already an issue and a pull request about this. Feel free to close?
I'm trying to calculate the normal of a triangle:
// A triangle
let x = Pnt3::new(0.0f32, 1.0, 0.0);
let y = Pnt3::new(0.0f32, 1.0, 1.0);
let z = Pnt3::new(1.0f32, 0.0, 1.0);
let v = y - x; // first side
let w = z - x; // second side
let n = cross(v, w); // the normal
I get this however:
/Users/brendan/dev/projects/voyager/experiments/village/src/main.rs:153:13: 153:18 error: the trait `nalgebra::structs::pnt::Pnt3SubRhs<f32, &_>` is not implemented for the type `nalgebra::structs::pnt::Pnt3<f32>`
/Users/brendan/dev/projects/voyager/experiments/village/src/main.rs:153 let v = y - x; // first side
^~~~~
/Users/brendan/dev/projects/voyager/experiments/village/src/main.rs:154:13: 154:18 error: the trait `nalgebra::structs::pnt::Pnt3SubRhs<f32, &_>` is not implemented for the type `nalgebra::structs::pnt::Pnt3<f32>`
/Users/brendan/dev/projects/voyager/experiments/village/src/main.rs:154 let w = z - x; // second side
^~~~~
I am seriously considering transitioning from my cgmath
library to nalgebra, seeing as it is now insanely well polished, and it would allow me to use your collision and physics stuff without having to re-invent the wheel. Some of the things I love about cgmath
though is:
(*) : Point a -> a -> Point a
(/) : Point a -> a -> Point a
(+) : Point a -> Vector a -> Point a
(-) : Point a -> Point a -> Vector a
These things don't really make sense for a linear algebra library, but is it possible that we could have a separate library for these?
This generic implementation would handle both DMat
and statically-sized matrices.
See the original discussion here: #6.
I'm not sure about this, but I believe that what I want is to have a 4x4 matrix which represents affine transformations and I want to add a rotation to that. So I create a UnitQuat and then I want to modify my 4x4 matrix. So I would call unit_quat.to_rot().mult(my_4x4_matrix)
. But that does not work since to_rot returns a 3x3 matrix.
Perhaps a to_rot4()
function should be added which fills in 0's and a 1 on the diagonal for convenient use with a 4x4 transformation matrix?
As I understand it, the Iso
structure is used to represent both position and rotation of physical objects. Assume that I use pos
for an Iso
structure of position and rotation as one, and vel
for another Iso
structure to specify velocity. Would it be add scalar multiplication to Iso
to allow this:
cube.pos = cube.pos + cube.vel * dt
The macros have to be adjusted mainly. I started working on this.
Since having updated my rust-nightly, nalgebra doesn't compile anymore due to a myriad of error: cannot declare a new module at this location
. However, I didn't find anything relevant in Rust weekly news and I'm too newb to find the problem.
These don't seem to be supported yet.
I was looking for a way to convert [f32, ..2]
into a Vec2<f32>
when I found this:
Is there any reason to take self
?
This is a general issue that should be addressed now, that 1.0-beta will be out in a couple of days.
nalgebra
is still using the following unstable features:
unboxed_closures
are opted-in but apparently unused. Can be removed.core
contains a bunch of numerical things we really need. Should be audited in detail. Maybe some of this has to be migrated to use the num crate.std_misc
only for Float::{max_value, min_value}
in non-generic places. Eventually this should become better with associated constants, but for now it can be removed.test
for benchmarking. According to the latest meeting minutes there is some plan for making benchmarks available, though I don't clearly see how that's going to work. We need to observe this situation.Currently the trait methods are static, making them harder to use than the free functions. We should make them non-static, so that the user has a choice on which style he prefers.
Initial discussion #35
Should the vector and matrix structs have #[repr(C)]
? Without that, I suspect the compiler could rearrange the memory layout of the structs. That would cause weird and hard-to-debug errors when passing pointers to C APIs like OpenGL. E.g. when calling glBufferData
or gluniformmatrix4fv
.
I apologize if I'm mistaken about this. I'm new to Rust.
I have two DVec
s of type f32
. I want to multiply these two. However, the compiler tells me DVecMulRhs
trait is not implemented for multiplication with f32
. Same happens with f64
, and any other primitive type.
src/lib.rs:8:24: 8:33 error: the trait `nalgebra::structs::dvec::DVecMulRhs<f32, nalgebra::structs::dvec::DVec<f32>>`
is not implemented for the type `nalgebra::structs::dvec::DVec<f32>`
src/lib.rs:8 let h: DVec<f32> = X * Y;
I'm pretty sure your operator overloading is done correctly, so I must be doing something wrong. Can't quite figure out what:
fn compute_cost(X: DVec<f32>, Y: DVec<f32>) -> f32 {
let h: DVec<f32> = X * Y;
//...
}
I'm using Rust nightly-0.13.0
This is motivated mainly to allow a seamless interaction with piston libraries. Piston internally uses https://github.com/PistonDevelopers/vecmath, which are generic functions on static arrays ([T, ..n] or [[T, ..n], ..m]). Thus to interface with the libraries it is crucial to be able to convert vectors and matrices to and from static arrays seamlessly.
I don't know whether this warrants changing the internal representation to arrays. Transitioning from cgmath I find this a bit cumbersome to work around.
Static methods like Float::pi()
are deprecated so we will have to define them in our own trait BasicFloat
.
This should be a pretty straightforward change to the src/traits/structure.rs
file.
This seems simpler and more rustic. If folks want to be use an abbreviation for the crate name, they could do:
extern crate nalgebra as na;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.