Giter Club home page Giter Club logo

alga's People

Contributors

adamnemecek avatar annekitsune avatar aplund avatar atul9 avatar azriel91 avatar brendanzab avatar c4k3 avatar cuviper avatar daingun avatar dcrewi avatar eclipseo avatar exphp avatar fizyk20 avatar flaper87 avatar flier avatar hmunozb avatar ignatenkobrain avatar jonas-schievink avatar mark-schultz avatar omalaspinas avatar omasanori avatar sebcrozet avatar wadelma avatar waywardmonkeys avatar wiep avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alga's Issues

Is the Real trait is too broad? (or too specialized)

I think it would be beneficial to have traits for functions (exp, sin, pow, ...) that are separate from numbers (partialOrd, Signed, ...). For example, when one wants to use complex numbers (since ComplexNumbers are now implementing a lot of the alga traits now) it is not uniquely defined how to order them. Nevertheless it would be great to be able to have the exp, log, ... functions in a trait without requiring them to be ordered in any way. It would be an equivalent of the Num, NumOps trait of the num_trait crate.

What do you think?

Help implementing `Scalar` for dual number

I'm seeking help in implementing the Scalar trait for dual numbers, specifically for the dual_num crate (which is currently undergoing an upgrade to support automatic partial derivatives). Please correct me if I'm wrong, but I think that mathematically, a dual number is indeed scalar (in the case of dual_num it is represented as a na::Vector2 but that should not alter its mathematical properties).

The purpose for implementing Scalar for dual number is to greatly simplify mathematical operations when using dual numbers in conjunction with the nalgebra crate.

Thanks for the support

P.S.: I think that these dual numbers could be represented in a similar fashion to how Vec2<Scalar> is represented in this example. I'll try that out.

Polynomial ring over a finite field

Hello!

I would like to construct a polynomial ring over a finite field, but I am new to Rust and this type of math.
Can this library be used for this and, if so, can someone point me in the right direction?

Thanks!

Add prelude

Adding prelude so that usual usage of alga would look like this would be useful:

extern crate alga;
use alga::prelude::*

Instructions incomplete/incorrect on how to define an additive group

If I define an additive group according to the instructions in the documentation, it still will not satisfy the AdditiveGroup trait, and I can't do addition with it (e.g. element + element).

use alga::general::{AbstractMagma, Additive, AdditiveGroup, Identity, Inverse}; // 0.7.2
use alga_derive::Alga; // 0.7.1

#[derive(Alga, Clone, Copy, PartialEq, Debug)]
#[alga_traits(Group(Additive))]
pub struct TrivialGroup;

impl AbstractMagma<Additive> for TrivialGroup {
    fn operate(&self, _right: &Self) -> Self {
        TrivialGroup {}
    }
}

impl Identity<Additive> for TrivialGroup {
    fn identity() -> Self {
        TrivialGroup {}
    }
}

impl Inverse<Additive> for TrivialGroup {
    fn inverse(&self) -> Self {
        TrivialGroup {}
    }
}

struct Bar<T: AdditiveGroup> {
    t: T,
}

fn main() {
    let foo = Bar::<TrivialGroup> { t: TrivialGroup {} };
}

Gives the error:

error[E0277]: the trait bound `TrivialGroup: num_traits::identities::Zero` is not satisfied
  --> src/main.rs:31:15
   |
31 |     let foo = Bar::<TrivialGroup> { t: TrivialGroup {} };
   |               ^^^^^^^^^^^^^^^^^^^ the trait `num_traits::identities::Zero` is not implemented for `TrivialGroup`
   |
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveLoop` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveGroup` for `TrivialGroup`
note: required by `Bar`
  --> src/main.rs:26:1
   |
26 | struct Bar<T: AdditiveGroup> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `TrivialGroup: std::ops::Neg` is not satisfied
  --> src/main.rs:31:15
   |
31 |     let foo = Bar::<TrivialGroup> { t: TrivialGroup {} };
   |               ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Neg` is not implemented for `TrivialGroup`
   |
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::ClosedNeg` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveLoop` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveGroup` for `TrivialGroup`
note: required by `Bar`
  --> src/main.rs:26:1
   |
26 | struct Bar<T: AdditiveGroup> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: cannot subtract `TrivialGroup` from `TrivialGroup`
  --> src/main.rs:31:15
   |
31 |     let foo = Bar::<TrivialGroup> { t: TrivialGroup {} };
   |               ^^^^^^^^^^^^^^^^^^^ no implementation for `TrivialGroup - TrivialGroup`
   |
   = help: the trait `std::ops::Sub` is not implemented for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::ClosedSub` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveQuasigroup` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveLoop` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveGroup` for `TrivialGroup`
note: required by `Bar`
  --> src/main.rs:26:1
   |
26 | struct Bar<T: AdditiveGroup> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: cannot subtract-assign `TrivialGroup` from `TrivialGroup`
  --> src/main.rs:31:15
   |
31 |     let foo = Bar::<TrivialGroup> { t: TrivialGroup {} };
   |               ^^^^^^^^^^^^^^^^^^^ no implementation for `TrivialGroup -= TrivialGroup`
   |
   = help: the trait `std::ops::SubAssign` is not implemented for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::ClosedSub` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveQuasigroup` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveLoop` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveGroup` for `TrivialGroup`
note: required by `Bar`
  --> src/main.rs:26:1
   |
26 | struct Bar<T: AdditiveGroup> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: cannot add-assign `TrivialGroup` to `TrivialGroup`
  --> src/main.rs:31:15
   |
31 |     let foo = Bar::<TrivialGroup> { t: TrivialGroup {} };
   |               ^^^^^^^^^^^^^^^^^^^ no implementation for `TrivialGroup += TrivialGroup`
   |
   = help: the trait `std::ops::AddAssign` is not implemented for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::ClosedAdd` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveSemigroup` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveMonoid` for `TrivialGroup`
   = note: required because of the requirements on the impl of `_ALGA_DERIVE_TrivialGroup::_alga::general::AdditiveGroup` for `TrivialGroup`
note: required by `Bar`
  --> src/main.rs:26:1
   |
26 | struct Bar<T: AdditiveGroup> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

See also: https://stackoverflow.com/questions/54303935/defining-additivegroup-with-alga-crate

Are the real numbers a normed space?

I'm very much not a mathematician, nor am I a Rust expert, so please forgive me if this is a silly question.

I'm working on a spline implementation which I will mostly use for 3D curves, but I would also like it to work for 2D curves and for 1D (I don't know if those can still be called "curves").

For 2D and 3D I'm using vector types from the nalgebra crate (which implement several alga traits).

Since my implementation is supposed to work on any vector space that has a norm, I think it would make sense to use the alga::linear::NormedSpace trait bound.

For the 1D case I could of course use a 1D vector from nalgebra, but I think it would be much nicer if I could also use a "normal" scalar type, like e.g. f64.

This doesn't work though, because NormedSpace doesn't seem to be implemented for f64 (it looks like it's only implemented for Complex<N>).

Now my question: are real numbers a normed space?
I would think so, but what do I know ...

If that makes at least some mathematical sense, would it be possible to implement NormedSpace for scalars?

I'm thinking about something like this:

impl<T: RealField> NormedSpace for T {
    type RealField = T;

    ...

    fn norm(&self) -> T {
        self.abs()
    }

    ...
}

Or probably this should use ComplexField instead?

Separate linear operator from matrix trait

For context, this idea is motivated by vbarielle/sprs#118.

The matrix trait is rather large at the moment:

pub trait Matrix: Sized + Clone + Mul<Self::Row, Output = Self::Column> {
    type Field: Field;
    type Row: FiniteDimVectorSpace<Field = Self::Field>;
    type Column: FiniteDimVectorSpace<Field = Self::Field>;
    type Transpose: Matrix<Field = Self::Field, Row = Self::Column, Column = Self::Row>;
    fn nrows(&self) -> usize;
    fn ncolumns(&self) -> usize;
    fn row(&self, i: usize) -> Self::Row;
    fn column(&self, i: usize) -> Self::Column;
    unsafe fn get_unchecked(&self, i: usize, j: usize) -> Self::Field;
    fn transpose(&self) -> Self::Transpose;

    fn get(&self, i: usize, j: usize) -> Self::Field { ... }
}

For many algorithms, access to the internal structure of the matrix is not necessary. It also does put some burden on trait implementors that may be possible to avoid.

A suggested solution would be to introduce a more abstract linear operator inspired by SciPy's interface with the same name as a supertrait.

pub trait LinearOperator: Sized + Clone + Mul<Self::Row, Output = Self::Column> {
    type Field: Field;
    type Row: FiniteDimVectorSpace<Field = Self::Field>;
    type Column: FiniteDimVectorSpace<Field = Self::Field>;
    type Transpose: LinearOperator<Field = Self::Field, Row = Self::Column, Column = Self::Row>;
    fn nrows(&self) -> usize;
    fn ncolumns(&self) -> usize;
    fn transpose(&self) -> Self::Transpose;
}

pub trait Matrix: LinearOperator {
    fn row(&self, i: usize) -> Self::Row;
    fn column(&self, i: usize) -> Self::Column;
    unsafe fn get_unchecked(&self, i: usize, j: usize) -> Self::Field;
    fn get(&self, i: usize, j: usize) -> Self::Field { ... }
}

It would be useful to include matrix multiplication there as well, but I have a feeling that this is hard to express in today's Rust. It also seems like a separate issue as the original matrix trait does not include this either.

Rename Inverse to TwoSidedInverse

Currently the Inverse trait has a .inverse method that returns the inverse of an element with respect to a given operator (additive or multiplicative). We should rename this to avoid conflicts on types from other crates that have an inverse method and also implement Inverse from alga.

In particular, this can lead to very confusing scenarios where users call .inverse on Matrix4 from nalgebra and end up with the additive inverse where they actually needed try_inverse() to obtain the multiplicative inverse.

Renaming Inverse to TwoSidedInverse and .inverse to .two_sided_inverse will reduce the ambiguity and will make the name of this trait more precise anyway.

quickcheck 0.8

Fedora maintainer here!

I would appreciate if you would update quickcheck dependency to 0.8 so that won't have to ship multiple versions of quickcheck ;)

Metric spaces

cgmath currently has a MetricSpace trait that is defined for vectors, points, and quaternions:

pub trait MetricSpace: Sized {
    type Metric: BaseFloat;
    fn distance2(self, other: Self) -> Self::Metric;

    fn distance(self, other: Self) -> Self::Metric { ... }
}

Could we consider rejiggering the alga::linear trait hierarchy to add something like this?

Left multiplication for vector spaces

This code example fails:

fn foo<V: VectorSpace<Field=f64>>(a: V, b: V, c: f64) -> V {
    a * c + c * b
}

with this error:

error[E0277]: the trait bound `f64: std::ops::Mul<V>` is not satisfied
   |
   |     a * c + c * b
   |               ^ no implementation for `f64 * V`
   |
   = help: the trait `std::ops::Mul<V>` is not implemented for `f64`
   = help: consider adding a `where f64: std::ops::Mul<V>` bound

(omitted source location in my project for clarity)

Is there a reason, why this can't be made work? As multiplication on the field commutes anyway, the operator should generally be available in this way.

Deriving a Ring trait requires a two-sided multiplicative inverse

I am trying to implement the ring of integers mod n for n non-prime (so this is a ring, not a field). Here is a link to the relevant code.

The section which errors has the following form:

#[derive(Clone, Copy, PartialEq, Alga)]
#[alga_traits(Ring(Additive, Multiplicative))]
struct Modular<const Q: u32>(u32);

The rest of the code is implementing various traits.
The particular error is below:

error[E0277]: the trait bound `Modular<Q>: TwoSidedInverse<Multiplicative>` is not satisfied
  --> src/lib.rs:10:34
   |
10 | #[derive(Clone, Copy, PartialEq, Alga)]
   |                                  ^^^^ the trait `TwoSidedInverse<Multiplicative>` is not implemented for `Modular<Q>`
   |
  ::: /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/alga-0.9.3/src/general/one_operator.rs:49:36
   |
49 |     PartialEq + AbstractMagma<O> + TwoSidedInverse<O>
   |                                    ------------------ required by this bound in `AbstractQuasigroup`
   |
   = help: the following implementations were found:
             <Modular<Q> as TwoSidedInverse<Additive>>
   = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `Modular<Q>: TwoSidedInverse<Multiplicative>` is not satisfied
   --> src/lib.rs:10:34
    |
10  | #[derive(Clone, Copy, PartialEq, Alga)]
    |                                  ^^^^ the trait `TwoSidedInverse<Multiplicative>` is not implemented for `Modular<Q>`
    |
   ::: /home/mark/.cargo/registry/src/github.com-1ecc6299db9ec823/alga-0.9.3/src/general/one_operator.rs:189:38
    |
189 | pub trait AbstractLoop<O: Operator>: AbstractQuasigroup<O> + Identity<O> {}
    |                                      --------------------- required by this bound in `AbstractLoop`
    |
    = help: the following implementations were found:
              <Modular<Q> as TwoSidedInverse<Additive>>
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `latticecrypto`

To learn more, run the command again with --verbose.

It seems that the issue is that I have not provided a TwoSidedInverse implementation. But I want to implement an integral domain for which not every element has a multiplicative inverse, so this seems like the "right" thing to be doing.
Is this behavior expected? Is there some other way that I can use alga to implement the modular arithmetic mod n for n composite?

re-export num-complex/rustc-serialize

It would be nice to make the obsoleted rustc-serialize optional by adding it as a default feature that could be turned off. I'm having a hard time compiling to a specific target and it looks like rustc-serialize is the culprit.

Not sure if there's anything in alga that specifically relies on it though.

InnerSpace Angle Implementation Bug

The implementation of angle function on trait InnerSpace is incorrect. When calculating cang, instead of multiplying the inner product by the norms of two vectors, it should be dividing them.

The correct calculation should be let cang = prod.real().unscale(n1 * n2);.

RealField/ComplexField traits

Thank you all so much for adding in complex support! It makes my project 100x easier now that I can use existing matrix functions with complex numbers. I have just a few lingering concerns about the traits.

First of all, would it be possible to remove the Bounded requirement of RealField? Although this would be a breaking change, it would allow using arbitrary-size numbers or rationals, as long as they implement Copy. I understand the argument that they should probably implement Clone instead, but on the other hand, I seriously doubt that many functions rely on Bounded, and that could be added as a generic requirement for those limited cases. Furthermore, using Bounded does not really make much sense for floating point numbers anyway since it is almost always impractical that any number should ever come even close to the maximum possible float (since they store an exponent and significand rather than a binary number like u8; f64::MAX > 10308).

Second, is the 'static requirement for ComplexField really necessary? Yes, I know that removing this would be very breaking, and make things a bit more difficult to write, but I IMHO at least eventually it is a necessary step in order to write any performant code using alga in order to avoid memory leaks. Same goes for Send, Sync, Any, and Debug/Display. As is the case for Bounded, I think it would make more sense for rarely-used requirements like these to be specified for individual functions and to only require the real necessities like arithmetic as a requirement for all ComplexField and thereby RealField numbers.

Third, one more breaking change: would it be possible to eventually refactor the requirements for trigonometric/hyperbolic/exponential/logarithmic, etc. functions into requirements for the corresponding traits in num_traits? This would make implementing those functions easier. Or better yet, at least for RealField, would it be possible to remove those requirements except for the functions that use them?


Overall, the most important request I have is removing 'static. Everything else is just a suggestion/proposal, but IMHO removing 'static is essential for proper memory management even if it makes generics a bit more difficult.

Thank you again, and please note that everything here is just ideas for consideration and not feature requests. I understand if not everything here would make sense to implement.

Quickcheck for everyone!

Currently alga uses quickcheck for it's own tests.
It should provide straight forward way for it's users to make use of it too.

One avenue worth exploring would be to include quickcheck test with the convenience macros that I added.

(This wish came about implementing geometric algebra library: https://github.com/WaDelma/galgebra. It's quite WIP and propably wrong as I am just now trying to figure this whole thing out :D)

FiniteDimVectorSpace forces every type of vectors to have the same rank

Recall this definition:

pub trait FiniteDimVectorSpace: VectorSpace + Index<usize, Output = Self::Field> + IndexMut<usize, Output = Self::Field> {
    fn dimension() -> usize;
    fn canonical_basis_element(i: usize) -> Self;
    fn dot(&self, other: &Self) -> Self::Field;
    unsafe fn component_unchecked(&self, i: usize) -> &Self::Field;
    unsafe fn component_unchecked_mut(&mut self, i: usize) -> &mut Self::Field;

    fn canonical_basis<F: FnMut(&Self) -> bool>(f: F) { ... }
}

Note that FiniteDimVectorSpace::dimension is independent of &self. This forces all implementors of this trait to return constant value. Therefore, Vec<T> where T: Field is not a vector over the field T.

This is an awkward definition. It might make some sense for vector space of a certain dimension known at compile time, such as Vec2 and Vec3 in the examples. However, it prohibits implementations in general.

The dimension associated method in the definition of SquareMatrix makes much less sense in this context. Recall its definition:

pub trait SquareMatrix: Matrix<Row = Self::Vector, Column = Self::Vector, Transpose = Self> + MultiplicativeMonoid {
type Vector: FiniteDimVectorSpace<Field = Self::Field>;
    fn diagonal(&self) -> Self::Vector;
    fn determinant(&self) -> Self::Field;
    fn try_inverse(&self) -> Option<Self>;

    fn dimension(&self) -> usize { ... }
    fn transpose_mut(&mut self) { ... }
}

The dimension associated method in this case takes &self, but it is in fact independent of &self once Self::Vector has constant rank at compile time.

The proposed change is to allow FiniteDimVectorSpace::dimension to accept &self.

Publish new version of `alga_derive`

Hiya, currently alga-derive on crates.io still uses syn 0.15, but in the repository it already is bumped to syn 1.0. Please may we have a release of alga-derive 0.9.2 to receive the update? Thank you!

Automatic deriving of module-like structures

There is currently two problems with this:

  • AbstractModule contains multiply_by making it non-marker trait.
    • Move it to separate trait
    • Add way to specify what it does from custom attribute
  • Both VectorSpace (the fact that this isn't called AbstractVectorSpace needs to be hardcoded) and AbstractModule have associated type that needs to be specified somehow.

decimal::d128 with alga::general::real

I suspect this is more of a usage error than a bug, but can't anywhere else to go for help.

I'm trying to use the ncollision2d and decimal crates, and keep getting this error:

error[E0277]: the trait bound `decimal::d128: alga::general::Real` is not satisfied
  --> src/misc.rs:86:3
   |
86 |   pub cuboid: Cuboid<d128>,
   |   ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `alga::general::Real` is not implemented for `decimal::d128`
   |
   = note: required by `ncollide2d::shape::Cuboid`

Among others, I have this in my Cargo.toml:

[dependencies]
ncollide2d = "0.17.1"
decimal = "2.0.4"

[dependencies.alga]
version = "0.7.1"
features = ["decimal"]

As far as I can tell, that should enable the Real trait for decimal, but it isn't working. Is this a problem with alga? If not, can you tell me what I'm missing?

Thanks.

Deprecate macro_rules based deriving

As there now is custom derive based solution macro_rules based one isn't nessary.

Only thing that macro_rules based one allows that custom derive doesn't is to implement the trait for types not in current crate. Because how orphan rules work this is only relevant to alga itself.

So I propose removing #[macro_export] from all of the macros.

Operations on references

I found that writing generic arithmetic with alga involves some extra clones. The reason is, that there is no way to apply operators to references. Therefore you have to pass ownership to the operator, which requires a clone, as soon as you need a value more than once.

For example, given two (large) vectors, a: T and b: U, where T: ClosedAdd<U>, I would like to be able to do all of these operations:

// possible today
a + b
a += b
// not possible without adding extra trait bounds
a + &b
&a + b
&a + &b
a += &b

That would probably require the ClosedAdd trait to be extended to this

trait ClosedAdd<Right = Self>:
    Sized +
    Add<Right, Output = Self> +
    for<'a> Add<&'a Right, Output = Self> +
    AddAssign<Right> +
    for<'a> AddAssign<&'a Right>
where
    for<'a> &'a Self: Add<Right, Output = Self>,
    for<'a, 'b> &'a Self: Add<&'b Right, Output = Self>
{}

Of course, this adds extra burden on trait implementors. It is also a backwards-incompatible change, as it breaks implementations that do not fulfill the extra bounds yet. (afaik, at least nalgebra should be fine.)

I would argue, that any arithmetic type should be able to handle these cases. Happy to hear a counter-example, but I can't really think of any yet.

Add DirectSimilarity trait

This would be a breaking change, because presumably DirectIsometry implementors would also be required to implement DirectSimilarity<Scaling=Id>. However, this would be very useful for things like the transformations on an entity in a graphical scene, where zero or negative scales can cause ugly problems.

FiniteDimVectorField should be implemented for `f64`and `f32`

The FiniteDimVectorField should be implemented for the f32 and f64 type.

A motivating example is the representation of an Initial Value Problem.

extern crate alga;

use alga::general::RealField;
use alga::linear::FiniteDimVectorSpace;

pub struct IVPProblem<'a, T, S>                                                                                                                                                                                                                
where                                                                                                                                                                                                                                          
    T : RealField,                                                                                                                                                                                                                             
    S : FiniteDimVectorSpace<Field = T>                                                                                                                                                                                                        
{                                                                                                                                                                                                                                              
    initial_state : S,                                                                                                                                                                                                                         
    tspan: (T,T),                                                                                                                                                                                                                              
    func : &'a dyn Fn(&T, &S) -> S,                                                                                                                                                                                                            
}                                                                                                                                                                                                                                              

If we would now want to implement the exponential equation given by dy/dt=dy you could try to implement it as

fn main() {
        let ivp_problem =  IVPProblem {                                                                                                                                                                                                        
            initial_state : 1.0,                                                                                                                                                                                                               
            tspan : (0.0, 1.0),                                                                                                                                                                                                                
            func : &(|_, &y| y)                                                                                                                                                                                                                                                                                                                                                                                                                                               
        };     

        /// More code here
}

This would not compile because our initial_state is an f64-type and the trait FiniteDimVectorSpace<Field = f64> is not implemented.

Considering NaN, do floating point values form a lattice?

alga implements the Lattice trait for primitive f32 and f64 types while providing infallible pair-wise meet and join operations. This seems to interact poorly with NaNs, which do not compare with other floating point values regardless of what they encode (the result is always false with the sole exception of !=).

Given this comparison and some floating point value x, (NaN ∨ x) produces x while (x ∨ NaN) produces NaN, because NaN >= x and x >= NaN are never true. Considering that NaN has no ordering w.r.t. any elements in the set of floating point values, can there be a greatest lower bound or least upper bound?

If the intention is to simply propagate NaNs as a sort of special case (rather than using a fallible API via Option or Result), then perhaps the implementation should produce NaN if either operand is NaN. "Garbage in, garbage out" probably applies here as well. :-) Do you have any thoughts on this?

Consider softening the demands on ComplexField

If I understand correctly every RealField must implement ComplexField (with the imaginary part set to zero) and every ComplexField must be a super-set of f64, that is, it must be able to represent all values of f64 logically (disregarding machine specific limitations). Decorum's N64 and R64 types logically cannot be NotANumber or Infinity. They thus are not logical super-sets of f64.

For my calculations results of NaN or Infinity are logical errors. I put finite numbers in and expect my calculations to result in finite numbers. I'd thus like to use Deorum's numbers.

My attempt to implement the traits, required for ComplexField, failed at the above requirement. Would it be possible to remove the requirement or replace it by a softer requirement, like Decorum's Real or Real+Encoding?

Missing Integer alias trait

There is a Real trait but not a ready-to-use Integer trait.
Now I'm using the RingCommutative trait to define the classical integer number set, but there is no motivation for not introduce an alias trait Integer.

Am I missing something?

Update syn dependency

Hello,

alga_derive is the only one in Fedora which pulls syn 0.11, the rest is using 0.15. I would appreciate if you would update dependency.

Thanks!

unnecessary parentheses around function argument

Extra parens at alga/alga/src/linear/transformation.rs:371:14 keep the library from compiling. Some((b.norm() / a.norm())) -> Some(b.norm() / a.norm()) fixes it.

Error message
cargo build
   Compiling alga v0.5.2 (file:///Users/wbeard/repos/proto/hello_alg/alga/alga)
warning: unused macro definition
   --> alga/alga/src/macros.rs:143:1
    |
143 | / macro_rules! impl_approx_eq {
144 | |     ($V:expr; $($T:ty),* $(,)*) => {
145 | |         $(impl ApproxEq for $T {
146 | |             type Eps = $T;
...   |
158 | |     }
159 | | }
    | |_^
    |
    = note: #[warn(unused_macros)] on by default

warning: unused macro definition
--> alga/alga/src/general/one_operator.rs:84:1
|
84 | / macro_rules! impl_quasigroup(
85 | | (<$M:ty> for $($T:tt)+) => {
86 | | impl_marker!($crate::general::AbstractQuasigroup<$M>; $($T)+);
87 | | }
88 | | );
| |__^

warning: unused macro definition
--> alga/alga/src/general/one_operator.rs:184:1
|
184 | / macro_rules! impl_loop(
185 | | (<$M:ty> for $($T:tt)+) => {
186 | | impl_quasigroup!(<$M> for $($T)+);
187 | | impl_marker!($crate::general::AbstractLoop<$M>; $($T)+);
188 | | }
189 | | );
| |__^

error: unnecessary parentheses around function argument
--> alga/alga/src/linear/transformation.rs:371:14
|
371 | Some((b.norm() / a.norm()))
| ^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
|
note: lint level defined here
--> alga/alga/src/lib.rs:18:9
|
18 | #![deny(unused_parens)]
| ^^^^^^^^^^^^^

error: aborting due to previous error

error: Could not compile alga.

To learn more, run the command again with --verbose.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.