Skip to content
New issue

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.

Already on GitHub? Sign in to your account

Unable to compile Nelder-Mead example #115

Closed
HeavyMetalGeek opened this issue May 2, 2021 · 13 comments
Closed

Unable to compile Nelder-Mead example #115

HeavyMetalGeek opened this issue May 2, 2021 · 13 comments

Comments

@HeavyMetalGeek
Copy link

Note: I had to switch to building with the nightly toolchain because of issues with ndalgebra v0.26.2 due to "feature resolver isrequired"

I attempted to compile and run the Nelder-Mead example using the following in my Cargo.toml:

[dependencies]
argmin = { version = "0.4.4", features = ["ctrlc", "ndarrayl", "nalgebral"] }
argmin_testfunctions = "*"
ndarray = { version = "0.15", features = ["serde"] }

Adding features = ["serde"] was added to eliminate Serialize and Deserialize errors. Now I am getting the following errors:

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied    
  --> src\main.rs:36:30
   |
36 |           .with_initial_params(vec![
   |  ______________________________^
37 | |             // array![-2.0, 3.0],
38 | |             // array![-2.0, -1.0],
39 | |             // array![2.0, -1.0],
...  |
42 | |             array![2.0, -1.0],
43 | |         ])
   | |_________^ the trait `ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:36:30
   |
36 |           .with_initial_params(vec![
   |  ______________________________^
37 | |             // array![-2.0, 3.0],
38 | |             // array![-2.0, -1.0],
39 | |             // array![2.0, -1.0],
...  |
42 | |             array![2.0, -1.0],
43 | |         ])
   | |_________^ the trait `ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:36:30
   |
36 |           .with_initial_params(vec![
   |  ______________________________^
37 | |             // array![-2.0, 3.0],
38 | |             // array![-2.0, -1.0],
39 | |             // array![2.0, -1.0],
...  |
42 | |             array![2.0, -1.0],
43 | |         ])
   | |_________^ the trait `ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:35:18
   |
35 |     let solver = NelderMead::new()
   |                  ^^^^^^^^^^^^^^^ the trait `ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`   
   |
   = note: required by `NelderMead::<P, F>::new`

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:35:18
   |
35 |     let solver = NelderMead::new()
   |                  ^^^^^^^^^^^^^^^ the trait `ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`   
   |
   = note: required by `NelderMead::<P, F>::new`

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:35:18
   |
35 |     let solver = NelderMead::new()
   |                  ^^^^^^^^^^^^^^^ the trait `ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
   |
   = note: required by `NelderMead::<P, F>::new`

error[E0599]: the method `sd_tolerance` exists for struct `NelderMead<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, _>`, but its trait bounds were not satisfied
    --> src\main.rs:44:10
     |
44   |           .sd_tolerance(0.0001);
     |            ^^^^^^^^^^^^ private field, not a method
     | 
    ::: C:\Users\Nobody\.cargo\registry\src\github.com-1ecc6299db9ec823\ndarray-0.15.1\src\lib.rs:1276:1
     |
1276 | / pub struct ArrayBase<S, D>
1277 | | where
1278 | |     S: RawData,
1279 | | {
...    |
1289 | |     strides: D,
1290 | | }
     | | -
     | | |
     | | doesn't satisfy `_: ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
     | |_doesn't satisfy `_: ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
     |   doesn't satisfy `_: ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
     |
     = note: the following trait bounds were not satisfied:
             `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
             `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
             `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`

Let me know if there is any further information I can provide.

@stefan-k
Copy link
Member

stefan-k commented May 2, 2021

Hi,

if you are not using nalgebra then I would suggest removing the nalgebral feature from your Cargo.toml. Your other issue seems to be coming from the wrong version of ndarray. argmin uses ndarray-linalg which so far does not support version 0.15 of ndarray. I think this problem will resolve when you switch to version 0.14 of ndarray.

@HeavyMetalGeek
Copy link
Author

[dependencies]
argmin = { version = "0.4.4", features = ["ctrlc", "ndarrayl"] }
argmin_testfunctions = "*"
ndarray = { version = "0.14", features = ["serde"] }

resulted in "error: linking with link.exe failed: exit code: 1120"

[dependencies]
argmin = { version = "0.4.4", features = ["ctrlc"] }
argmin_testfunctions = "*"
ndarray = { version = "0.14", features = ["serde"] }

resulted in the same errors I previously posted.

@stefan-k
Copy link
Member

stefan-k commented May 2, 2021

The first one should be correct, the second one can't work. I have never compiled argmin on windows and I don't have a windows computer available, therefore I can't debug this unfortunately. But since it is a linking error it may be related to linking against a BLAS library or something. Can you compile your code without the argmin dependency/code, just with ndarray?

@HeavyMetalGeek
Copy link
Author

I successfully compiled and ran a minimal example:

extern crate ndarray;
use ndarray::{array, Array1, Array2};

fn main() {
    let a = vec![array![1.0, 2.0], array![3.0, 4.0]];
    for i in &a {
        println!("{}", i);
    }
}

without issue. Let me know if there is something else you would like me to try.

@stefan-k
Copy link
Member

stefan-k commented May 3, 2021

I think you might be missing an external library, but I don't know which.

Could you try to compile without the ctrlc feature?

@HeavyMetalGeek
Copy link
Author

Using the following within Cargo.toml:

[dependencies]
argmin = { version = "0.4.4", features = ["ndarrayl"] }
argmin_testfunctions = "*"
ndarray = { version = "0.14", features = ["serde"] }

and adding extern crate argmin; to the previous minimal example yields linker errors. Removal of extern crate argmin; yields a successful build.

@stefan-k
Copy link
Member

stefan-k commented May 8, 2021

Thanks a lot for reporting this and your fix! Rust removed the necessity to use extern crate a while ago, but if I remember correctly, it was still necessary to use it in examples. Apparently it is not necessary anymore, therefore I've removed it from the examples in PR #116.

@stefan-k stefan-k closed this as completed May 8, 2021
@HeavyMetalGeek
Copy link
Author

HeavyMetalGeek commented May 8, 2021

I'm sorry if I was unclear. I did not find a fix. However, I did find that removing features=["ndarrayl"] from my argmin dependency took care of my linker errors. The following still produces errors with NelderMead::new() and sd_tolerance():

Cargo.toml

[dependencies]
argmin = { version = "0.4.4" }
argmin_testfunctions = "*"
ndarray = { version = "0.14", features = ["serde"] }

main.rs

use argmin::prelude::*;
use argmin::solver::neldermead::NelderMead;
use argmin_testfunctions::rosenbrock;
use ndarray::{array, Array1, Array2};

/// First, create a struct for your problem
struct Rosenbrock {
    a: f64,
    b: f64,
}

/// Implement `ArgminOp` for `Rosenbrock`
impl ArgminOp for Rosenbrock {
    type Param = Array1<f64>;
    type Output = f64;
    type Hessian = Array2<f64>;
    type Jacobian = ();
    type Float = f64;

    fn apply(&self, p: &Self::Param) -> Result<Self::Output, Error> {
        Ok(rosenbrock(&p.to_vec(), self.a, self.b))
    }
}

fn run() -> Result<(), Error> {
    // Define cost function
    let cost = Rosenbrock { a: 1.0, b: 100.0 };

    // Set up solver -- note that the proper choice of the vertices is very important!
    let solver = NelderMead::new()
        .with_initial_params(vec![
            // array![-2.0, 3.0],
            // array![-2.0, -1.0],
            // array![2.0, -1.0],
            array![-1.0, 3.0],
            array![2.0, 1.5],
            array![2.0, -1.0],
        ])
        .sd_tolerance(0.0001);

    // Run solver
    let res = Executor::new(cost, solver, array![])
        .add_observer(ArgminSlogLogger::term(), ObserverMode::Always)
        .max_iters(100)
        .run()?;

    // Wait a second (lets the logger flush everything before printing again)
    std::thread::sleep(std::time::Duration::from_secs(1));

    // Print result
    println!("{}", res);
    Ok(())
}

fn main() {
    if let Err(ref e) = run() {
        println!("{}", e);
        std::process::exit(1);
    }
}

Produces the following errors

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:39:30
   |
39 |           .with_initial_params(vec![
   |  ______________________________^
40 | |             // array![-2.0, 3.0],
41 | |             // array![-2.0, -1.0],
42 | |             // array![2.0, -1.0],
...  |
45 | |             array![2.0, -1.0],
46 | |         ])
   | |_________^ the trait `ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:39:30
   |
39 |           .with_initial_params(vec![
   |  ______________________________^
40 | |             // array![-2.0, 3.0],
41 | |             // array![-2.0, -1.0],
42 | |             // array![2.0, -1.0],
...  |
45 | |             array![2.0, -1.0],
46 | |         ])
   | |_________^ the trait `ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:39:30
   |
39 |           .with_initial_params(vec![
   |  ______________________________^
40 | |             // array![-2.0, 3.0],
41 | |             // array![-2.0, -1.0],
42 | |             // array![2.0, -1.0],
...  |
45 | |             array![2.0, -1.0],
46 | |         ])
   | |_________^ the trait `ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:38:18
   |
38 |     let solver = NelderMead::new()
   |                  ^^^^^^^^^^^^^^^ the trait `ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`   
   |
   = note: required by `NelderMead::<P, F>::new`

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:38:18
   |
38 |     let solver = NelderMead::new()
   |                  ^^^^^^^^^^^^^^^ the trait `ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`   
   |
   = note: required by `NelderMead::<P, F>::new`

error[E0277]: the trait bound `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not satisfied
  --> src\main.rs:38:18
   |
38 |     let solver = NelderMead::new()
   |                  ^^^^^^^^^^^^^^^ the trait `ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>` is not implemented for `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
   |
   = note: required by `NelderMead::<P, F>::new`

error[E0599]: no method named `sd_tolerance` found for struct `NelderMead<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, _>` in the current scope
    --> src\main.rs:47:10
     |
47   |           .sd_tolerance(0.0001);
     |            ^^^^^^^^^^^^ private field, not a method
     | 
    ::: C:\Users\Nobody\.cargo\registry\src\github.com-1ecc6299db9ec823\ndarray-0.14.0\src\lib.rs:1228:1
     |
1228 | / pub struct ArrayBase<S, D>
1229 | | where
1230 | |     S: RawData,
1231 | | {
...    |
1241 | |     strides: D,
1242 | | }
     | | -
     | | |
     | | doesn't satisfy `_: ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
     | |_doesn't satisfy `_: ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
     |   doesn't satisfy `_: ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
     |
     = note: the method `sd_tolerance` exists but the following trait bounds were not satisfied:
             `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminAdd<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
             `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminSub<ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`
             `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>: ArgminMul<_, ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>>`

error: aborting due to 7 previous errors; 1 warning emitted

@stefan-k stefan-k reopened this May 8, 2021
@stefan-k
Copy link
Member

stefan-k commented May 8, 2021

You need the ndarrayl feature when you want to use ndarray arrays with argmin, otherwise the corresponding math traits aren't implemented for the ndarray types.
I'm a bit confused, if removing extern crate argmin; didn't solve this problem, what did it solve then?

@HeavyMetalGeek
Copy link
Author

I'm sorry. I'm fairly new to Rust and am probably not conveying details in an efficient manner. I was simply stating that, while still having the ndarrayl feature in the argmin dependencies, the argmin packages (or its dependencies) were the source of the linker errors, even after removing the ctrlc feature.

After adding the ndarrayl feature back into the argmin dependency, I copied everything to Replit to test in a linux environment and it builds fine. On Windows, however, I get linker errors and I can't seem to figure out what could be the cause. I thought maybe rust-lang/rustup#1455 would be a good reference, but I have only run into linker errors when using the argmin crate and I already had the Windows SDK installed from my Visual Studio installation and adding the path to link.exe to my PATH environment variable made no impact.

If there is anything I can do to weed out the issue and convey the results more efficiently, I am certainly open to criticism.

@stefan-k
Copy link
Member

stefan-k commented May 9, 2021

I apologize if I sounded rude, that was not my intention.
Thank you for clarifying, I think I understand now. Just to summarize: You will need the ndarrayl feature, therefore the linking issue is the one that needs fixing (not the trait not implemented errors). ndarray-linalg, which is also used by argmin, links against a BLAS backend. According to their readme, the only BLAS backend which works on Windows is Intel-MKL. Do you have this installed? If not, I suggest you try to install it. You might even have to add ndarray-linalg to your Cargo.toml:

ndarray-linalg = { version = "0.13", features = ["intel-mkl-static"] } # apparently downloads Intel MKL itself, links statically
ndarray-linalg = { version = "0.13", features = ["intel-mkl-system"] } # Uses system Intel MKL, links dynamically

The best way to check if ndarray-linalg is causing this issue would probably be to try to compile one of their examples

@HeavyMetalGeek
Copy link
Author

Not at all. I just wanted to be clear about my inexperience so that you could factor that into your troubleshooting.

I added to my Cargo.toml:

ndarray-linalg = { version = "0.13", features = ["intel-mkl-static"] }

and that solved the linker issues, yielding a successful build. May I suggest adding something about this to the readme, under "Usage" for Windows users?

Thank you so much for your help and patience.

@stefan-k
Copy link
Member

Glad that this solved the problem! Thanks for giving all the various ideas a try. I will expand the readme in the near future to avoid this problem in the future. Thanks!

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

No branches or pull requests

2 participants