├── .gitignore ├── Cargo.toml ├── LICENSE.md ├── README.md ├── src ├── cg.rs ├── cg_minimizer.rs ├── lbfgsb.rs ├── lbfgsb_minimizer.rs ├── lib.rs ├── minimizer.rs └── string.rs └── tests └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | iterate.dat 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustimization" 3 | version = "0.1.1" 4 | authors = ["noshu "] 5 | license = "MIT" 6 | readme = "README.md" 7 | repository = "https://github.com/noshu/rustimization" 8 | homepage = "https://github.com/noshu/rustimization" 9 | documentation = "https://github.com/noshu/rustimization" 10 | description = """ 11 | A rust optimization library which includes L-BFGS-B and Conjugate Gradient algorithm 12 | """ 13 | [dependencies] 14 | lbfgsb-sys = "0.1.0" 15 | cg-sys = "0.1.0" 16 | libc = "0.2.11" -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Naushad Karim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rustimization 2 | 3 | A rust optimization library which includes **L-BFGS-B** and **Conjugate Gradient** algorithm. 4 | 5 | ## Documentation 6 | 7 | The simplest way to use these optimization algorithm is to use the Funcmin class. 8 | ```rust 9 | extern crate rustimization; 10 | use rustimization::minimizer::Funcmin; 11 | fn test(){ 12 | let f = |x: &Vec| { (x[0]+4.0).powf(2.0)}; 13 | let g = |x: &Vec| {vec![2.0*(x[0]+4.0)]}; 14 | let mut x = vec![40.0f64]; 15 | { 16 | //you must create a mutable object 17 | let mut fmin = Funcmin::new(&mut x,&f,&g,"cg"); 18 | fmin.minimize(); 19 | } 20 | println!("{:?}",x); 21 | } 22 | ``` 23 | Output 24 | ``` 25 | [-4.000000000000021] 26 | ``` 27 | here Funcmin constructor takes four **parameters** first one is initial estimation **x** second and third one is the function **f** and 28 | the derivative **g** of the function respectively and forth one is the algorithm you want to use. Currently two algorithms 29 | available **"cg"** and **"lbfgsb"** 30 | if you want more parameter tuning you can use the classes of the algorithm such as for Lbbfgsb_minimizer class 31 | 32 | ### Example 33 | 34 | ```rust 35 | let f = |x:&Vec|{ (x[0]+4.0).powf(2.0)}; 36 | let g = |x:&Vec|{vec![2.0*(x[0]+4.0)]}; 37 | let mut x = vec![40.0f64]; 38 | { 39 | //creating lbfgsb object. here it takes three parameter 40 | let mut fmin = Lbfgsb::new(&mut x,&f,&g); 41 | //seting upper and lower bound first parameter is the index and second one is value 42 | fmin.set_upper_bound(0,100.0); 43 | fmin.set_lower_bound(0,10.0); 44 | //set verbosity. higher value is more verbosity. the value is -1<= to <=101 45 | fmin.set_verbosity(101); 46 | //start the algorithm 47 | fmin.minimize(); 48 | } 49 | println!("{:?}",x); 50 | ``` 51 | Output 52 | ``` 53 | RUNNING THE L-BFGS-B CODE 54 | 55 | * * * 56 | 57 | Machine precision = 2.220D-16 58 | N = 1 M = 5 59 | 60 | L = 1.0000D+01 61 | 62 | X0 = 4.0000D+01 63 | 64 | U = 1.0000D+02 65 | 66 | At X0 0 variables are exactly at the bounds 67 | 68 | At iterate 0 f= 1.93600D+03 |proj g|= 3.00000D+01 69 | 70 | 71 | ITERATION 1 72 | 73 | ---------------- CAUCHY entered------------------- 74 | There are 1 breakpoints 75 | 76 | Piece 1 --f1, f2 at start point -7.7440D+03 7.7440D+03 77 | Distance to the next break point = 3.4091D-01 78 | Distance to the stationary point = 1.0000D+00 79 | Variable 1 is fixed. 80 | Cauchy X = 81 | 1.0000D+01 82 | 83 | ---------------- exit CAUCHY---------------------- 84 | 85 | 0 variables are free at GCP 1 86 | LINE SEARCH 0 times; norm of step = 30.000000000000000 87 | 88 | At iterate 1 f= 1.96000D+02 |proj g|= 0.00000D+00 89 | 90 | X = 1.0000D+01 91 | 92 | G = 2.8000D+01 93 | 94 | * * * 95 | 96 | Tit = total number of iterations 97 | Tnf = total number of function evaluations 98 | Tnint = total number of segments explored during Cauchy searches 99 | Skip = number of BFGS updates skipped 100 | Nact = number of active bounds at final generalized Cauchy point 101 | Projg = norm of the final projected gradient 102 | F = final function value 103 | 104 | * * * 105 | 106 | N Tit Tnf Tnint Skip Nact Projg F 107 | 1 1 2 1 0 1 0.000D+00 1.960D+02 108 | 109 | X = 1.0000D+01 110 | F = 196.00000000000000 111 | 112 | CONVERGENCE: NORM_OF_PROJECTED_GRADIENT_<=_PGTOL 113 | 114 | Cauchy time 1.570E-04 seconds. 115 | Subspace minimization time 0.000E+00 seconds. 116 | Line search time 1.800E-05 seconds. 117 | 118 | Total User time 9.330E-04 seconds. 119 | 120 | convergence! 121 | ``` 122 | 123 | ## Requirements 124 | 125 | To use this library you must have **gfortran** installed in your pc 126 | * for **windows** use fortran compiler provided by [mingw](http://www.mingw.org/) or [TDM-GCC](http://tdm-gcc.tdragon.net/) 127 | * for **linux** you can use the package manager to install gfortran 128 | * for Mac os you can install it form [here](http://hpc.sourceforge.net/) or [here](http://sourceforge.net/projects/hpc/files/hpc/g95/gfortran-mlion.tar.gz) 129 | 130 | The orginal **L-BFGS-B** fortran subroutine is distributed under BSD-3 license. To know more about the condition to use this fortran routine please go [here](http://users.iems.northwestern.edu/~nocedal/lbfgsb.html). 131 | 132 | To know more about the condition to use the **Conjugate Gradient** Fortran routine please go [here](http://users.iems.northwestern.edu/~nocedal/lbfgsb.html) 133 | 134 | ## References 135 | 136 | 1. R. H. Byrd, P. Lu and J. Nocedal. [A Limited Memory Algorithm for Bound Constrained Optimization](http://www.ece.northwestern.edu/~nocedal/PSfiles/limited.ps.gz), (1995), SIAM Journal on Scientific and Statistical Computing , 16, 5, pp. 1190-1208. 137 | 2. C. Zhu, R. H. Byrd and J. Nocedal. [L-BFGS-B: Algorithm 778: L-BFGS-B, FORTRAN routines for large scale bound constrained optimization](http://www.ece.northwestern.edu/~nocedal/PSfiles/lbfgsb.ps.gz) (1997), ACM Transactions on Mathematical Software, Vol 23, Num. 4, pp. 550 - 560. 138 | 3. J.L. Morales and J. Nocedal. [L-BFGS-B: Remark on Algorithm 778: L-BFGS-B, FORTRAN routines for large scale bound constrained optimization](http://www.ece.northwestern.edu/~morales/PSfiles/acm-remark.pdf) (2011), to appear in ACM Transactions on Mathematical Software. 139 | 4. J. C. Gilbert and J. Nocedal. Global Convergence Properties of Conjugate Gradient Methods for Optimization, (1992) SIAM J. on Optimization, 2, 1. 140 | 141 | 142 | -------------------------------------------------------------------------------- /src/cg.rs: -------------------------------------------------------------------------------- 1 | use cg_sys::cg as ffi; 2 | #[inline] 3 | pub fn step(n: i32, 4 | x: &mut [f64], 5 | f: f64, 6 | g: &[f64], 7 | d: &mut [f64], 8 | gold: &mut [f64], 9 | iprint: &[i32], 10 | w: &mut [f64], 11 | eps: f64, 12 | iflag: &mut i32, 13 | irest: i32, 14 | method: i32, 15 | finish: i32) { 16 | unsafe { 17 | ffi::cgfam_(&n, 18 | x.as_mut_ptr(), 19 | &f, 20 | g.as_ptr(), 21 | d.as_mut_ptr(), 22 | gold.as_mut_ptr(), 23 | iprint.as_ptr(), 24 | &eps, 25 | w.as_mut_ptr(), 26 | iflag, 27 | &irest, 28 | &method, 29 | &finish) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/cg_minimizer.rs: -------------------------------------------------------------------------------- 1 | use libc::{c_double, c_int}; 2 | use cg::step; 3 | pub struct CG<'a> { 4 | n: c_int, 5 | x: &'a mut Vec, 6 | d: Vec, 7 | gold: Vec, 8 | f: &'a Fn(&Vec) -> c_double, 9 | g: &'a Fn(&Vec) -> Vec, 10 | eps: c_double, 11 | w: Vec, 12 | iflag: c_int, 13 | irest: c_int, 14 | iprint: Vec, 15 | method: c_int, 16 | finish: c_int, 17 | max_iter: u32, 18 | } 19 | impl<'a> CG<'a> { 20 | // constructor requres three mendatory parameter which is the initial solution, function and the gradient function 21 | pub fn new(xvec: &'a mut Vec, 22 | func: &'a Fn(&Vec) -> c_double, 23 | gd: &'a Fn(&Vec) -> Vec) 24 | -> Self { 25 | let len = xvec.len() as i32; 26 | // creating CG struct 27 | CG { 28 | n: len, 29 | x: xvec, 30 | d: vec![0.0f64;len as usize], 31 | f: func, 32 | g: gd, 33 | eps: 1.0e-7, 34 | w: vec![0.0f64;len as usize], 35 | gold: vec![0.0f64;len as usize], 36 | iprint: vec![1, 3], 37 | iflag: 0, 38 | irest: 0, 39 | method: 1, 40 | max_iter: 10000, 41 | finish: 0, 42 | } 43 | } 44 | // this function will start the optimization algorithm 45 | pub fn minimize(&mut self) { 46 | let func = self.f; 47 | let grad = self.g; 48 | let mut fval = func(self.x); 49 | let mut gval = grad(self.x); 50 | let mut icall = 0; 51 | // start of the loop 52 | loop { 53 | // callign the fortran routine 54 | step(self.n, 55 | &mut self.x, 56 | fval, 57 | &gval, 58 | &mut self.d, 59 | &mut self.gold, 60 | &self.iprint, 61 | &mut self.w, 62 | self.eps, 63 | &mut self.iflag, 64 | self.irest, 65 | self.method, 66 | self.finish); 67 | icall += 1; 68 | if icall > self.max_iter { 69 | break; 70 | } 71 | match self.iflag { 72 | // geting the function and gradient value 73 | 1 => { 74 | fval = func(self.x); 75 | gval = grad(self.x); 76 | } 77 | // termination check 78 | 2 => { 79 | self.finish = 1; 80 | let tlev = self.eps * (1.0 + fval.abs()); 81 | for l in gval.iter().take(self.x.len()) { 82 | if *l > tlev { 83 | self.finish = 0; 84 | break; 85 | } 86 | } 87 | } 88 | _ => break, 89 | } 90 | } 91 | } 92 | // this function returns the solution after minimization 93 | pub fn get_x(&self) -> Vec { 94 | self.x.clone() 95 | } 96 | // set max iteration 97 | pub fn max_iteration(&mut self, i: u32) { 98 | self.max_iter = i; 99 | } 100 | // set restart 101 | pub fn set_restart(&mut self, b: bool) { 102 | self.irest = b as i32; 103 | } 104 | // set verbosity 105 | // vec[0] < 0 : NO OUTPUT IS GENERATED 106 | // vec[0] = 0 : OUTPUT ONLY AT FIRST AND LAST ITERATION 107 | // vec[0] > 0 : OUTPUT EVERY IPRINT(1) ITERATIONS 108 | // vec[1] : SPECIFIES THE TYPE OF OUTPUT GENERATED; 109 | // vec[1] = 0 : NO ADDITIONAL INFORMATION PRINTED 110 | // vec[1] = 1 : INITIAL X AND GRADIENT VECTORS PRINTED 111 | // vec[1] = 2 : X VECTOR PRINTED EVERY ITERATION 112 | // vec[1] = 3 : X VECTOR AND GRADIENT VECTOR PRINTED 113 | pub fn set_verbosity(&mut self, v: Vec) { 114 | self.iprint = v; 115 | } 116 | // set tolernace 117 | pub fn set_tolerance(&mut self, t: f64) { 118 | self.eps = t; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/lbfgsb.rs: -------------------------------------------------------------------------------- 1 | use lbfgsb_sys::lbfgsb as ffi; 2 | #[inline] 3 | pub fn step(n: i32, 4 | m: i32, 5 | x: &mut [f64], 6 | l: &[f64], 7 | u: &[f64], 8 | nbd: &[i32], 9 | f: f64, 10 | g: &[f64], 11 | factr: f64, 12 | pgtol: f64, 13 | wa: &mut [f64], 14 | iwa: &mut [i32], 15 | task: &mut [i8], 16 | iprint: i32, 17 | csave: &mut [i8], 18 | lsave: &mut [i32], 19 | isave: &mut [i32], 20 | dsave: &mut [f64]) { 21 | unsafe { 22 | ffi::setulb_(&n, 23 | &m, 24 | x.as_mut_ptr(), 25 | l.as_ptr(), 26 | u.as_ptr(), 27 | nbd.as_ptr(), 28 | &f, 29 | g.as_ptr(), 30 | &factr, 31 | &pgtol, 32 | wa.as_mut_ptr(), 33 | iwa.as_mut_ptr(), 34 | task.as_mut_ptr(), 35 | &iprint, 36 | csave.as_mut_ptr(), 37 | lsave.as_mut_ptr(), 38 | isave.as_mut_ptr(), 39 | dsave.as_mut_ptr()) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/lbfgsb_minimizer.rs: -------------------------------------------------------------------------------- 1 | use libc::{c_char, c_double, c_int}; 2 | use std::ffi::CStr; 3 | use lbfgsb::step; 4 | use string::stringfy; 5 | pub struct Lbfgsb<'a> { 6 | n: c_int, 7 | m: c_int, 8 | x: &'a mut Vec, 9 | l: Vec, 10 | u: Vec, 11 | nbd: Vec, 12 | f: &'a Fn(&Vec) -> c_double, 13 | g: &'a Fn(&Vec) -> Vec, 14 | factr: c_double, 15 | pgtol: c_double, 16 | wa: Vec, 17 | iwa: Vec, 18 | task: Vec, 19 | iprint: c_int, 20 | csave: Vec, 21 | lsave: Vec, 22 | isave: Vec, 23 | dsave: Vec, 24 | max_iter: u32, 25 | } 26 | impl<'a> Lbfgsb<'a> { 27 | // constructor requres three mendatory parameter which is the initial solution, function and the gradient function 28 | pub fn new(xvec: &'a mut Vec, 29 | func: &'a Fn(&Vec) -> c_double, 30 | gd: &'a Fn(&Vec) -> Vec) 31 | -> Self { 32 | let len = xvec.len() as i32; 33 | // creating lbfgs struct 34 | Lbfgsb { 35 | n: len, 36 | m: 5, 37 | x: xvec, 38 | l: vec![0.0f64;len as usize], 39 | u: vec![0.0f64;len as usize], 40 | nbd: vec![0;len as usize], 41 | f: func, 42 | g: gd, 43 | factr: 0.0e0, 44 | pgtol: 0.0e0, 45 | wa: vec![0.0f64;(2*5*len+11*5*5+5*len+8*5) as usize], 46 | iwa: vec![0;3*len as usize], 47 | task: vec![0;60], 48 | iprint: -1, 49 | csave: vec![0;60], 50 | lsave: vec![0, 0, 0, 0], 51 | isave: vec![0;44], 52 | dsave: vec![0.0f64;29], 53 | max_iter: 0, 54 | } 55 | } 56 | // this function will start the optimization algorithm 57 | pub fn minimize(&mut self) { 58 | let mut fval = 0.0f64; 59 | let mut gval = vec![0.0f64;self.x.len()]; 60 | let func = self.f; 61 | let grad = self.g; 62 | // converting fortran string "STRAT" 63 | stringfy(&mut self.task); 64 | // start of the loop 65 | loop { 66 | // callign the fortran routine 67 | step(self.n, 68 | self.m, 69 | &mut self.x, 70 | &self.l, 71 | &self.u, 72 | &self.nbd, 73 | fval, 74 | &gval, 75 | self.factr, 76 | self.pgtol, 77 | &mut self.wa, 78 | &mut self.iwa, 79 | &mut self.task, 80 | self.iprint, 81 | &mut self.csave, 82 | &mut self.lsave, 83 | &mut self.isave, 84 | &mut self.dsave); 85 | // converting to rust string 86 | let tsk = unsafe { CStr::from_ptr(self.task.as_ptr()).to_string_lossy() }; 87 | if &tsk[0..2] == "FG" { 88 | fval = func(self.x); 89 | gval = grad(self.x); 90 | } 91 | if &tsk[0..5] == "NEW_X" && self.max_iter == 0 && 92 | self.dsave[11] <= 1.0e-10 * (1.0e0 + fval.abs()) { 93 | println!("THE PROJECTED GRADIENT IS SUFFICIENTLY SMALL"); 94 | break; 95 | } 96 | if self.max_iter > 0 && self.isave[29] >= self.max_iter as i32 { 97 | break; 98 | } 99 | if &tsk[0..4] == "CONV" { 100 | println!("convergence!"); 101 | break; 102 | } 103 | if &tsk[0..5] == "ERROR" { 104 | println!("error in the input parameters"); 105 | } 106 | if &tsk[0..8] == "ABNORMAL" { 107 | println!("ERROR: ABNORMAL TERMINATION"); 108 | break; 109 | } 110 | } 111 | } 112 | // this function returns the solution after minimization 113 | pub fn get_x(&self) -> Vec { 114 | self.x.clone() 115 | } 116 | // this function is used to set lower bounds to a variable 117 | pub fn set_lower_bound(&mut self, index: usize, value: f64) { 118 | if self.nbd[index] == 1 || self.nbd[index] == 2 { 119 | println!("variable already has Lower Bound"); 120 | } else { 121 | let temp = self.nbd[index] - 1; 122 | self.nbd[index] = if temp < 0 { 123 | -temp 124 | } else { 125 | temp 126 | }; 127 | self.l[index] = value; 128 | } 129 | } 130 | // this function is used to set upper bounds to a variable 131 | pub fn set_upper_bound(&mut self, index: usize, value: f64) { 132 | if self.nbd[index] == 3 || self.nbd[index] == 2 { 133 | println!("variable already has Lower Bound"); 134 | } else { 135 | self.nbd[index] = 3 - self.nbd[index]; 136 | self.u[index] = value; 137 | } 138 | } 139 | // set the verbosity level 140 | pub fn set_verbosity(&mut self, l: i32) { 141 | self.iprint = l; 142 | } 143 | // set termination tolerance 144 | // 1.0e12 for low accuracy 145 | // 1.0e7 for moderate accuracy 146 | // 1.0e1 for extremely high accuracy 147 | pub fn set_termination_tolerance(&mut self, t: f64) { 148 | self.factr = t; 149 | } 150 | // set tolerance of projection gradient 151 | pub fn set_tolerance(&mut self, t: f64) { 152 | self.pgtol = t; 153 | } 154 | // set max iteration 155 | pub fn max_iteration(&mut self, i: u32) { 156 | self.max_iter = i; 157 | } 158 | // set maximum number of variable metric corrections 159 | // The range 3 <= m <= 20 is recommended 160 | pub fn set_matric_correction(&mut self, m: i32) { 161 | self.m = m; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate libc; 2 | extern crate lbfgsb_sys; 3 | extern crate cg_sys; 4 | pub mod lbfgsb_minimizer; 5 | pub mod lbfgsb; 6 | pub mod string; 7 | pub mod cg; 8 | pub mod cg_minimizer; 9 | pub mod minimizer; 10 | -------------------------------------------------------------------------------- /src/minimizer.rs: -------------------------------------------------------------------------------- 1 | use cg_minimizer::CG; 2 | use lbfgsb_minimizer::Lbfgsb; 3 | pub struct Funcmin<'a> { 4 | x: &'a mut Vec, 5 | f: &'a Fn(&Vec) -> f64, 6 | g: &'a Fn(&Vec) -> Vec, 7 | tol: f64, 8 | verbose: bool, 9 | method: &'a str, 10 | max_iter: u32, 11 | } 12 | impl<'a> Funcmin<'a> { 13 | // constructor requres three mendatory parameter which is the initial solution, function and the gradient function 14 | pub fn new(xvec: &'a mut Vec, 15 | func: &'a Fn(&Vec) -> f64, 16 | gd: &'a Fn(&Vec) -> Vec, 17 | m: &'a str) 18 | -> Self { 19 | // creating Funcmin struct 20 | Funcmin { 21 | x: xvec, 22 | f: func, 23 | g: gd, 24 | tol: 1.0e-7, 25 | max_iter: 10000, 26 | verbose: false, 27 | method: m, 28 | } 29 | } 30 | // this function will start the optimization algorithm 31 | pub fn minimize(&mut self) { 32 | let ver = if self.verbose { 33 | 0 34 | } else { 35 | 1 36 | }; 37 | { 38 | if self.method == "lbfgsb" { 39 | let mut minf = Lbfgsb::new(&mut self.x, self.f, self.g); 40 | minf.set_verbosity(ver); 41 | minf.set_tolerance(self.tol); 42 | minf.max_iteration(self.max_iter); 43 | minf.minimize(); 44 | } else if self.method == "cg" { 45 | let mut minf = CG::new(&mut self.x, self.f, self.g); 46 | minf.set_verbosity(vec![ver, 0]); 47 | minf.set_tolerance(self.tol); 48 | minf.max_iteration(self.max_iter); 49 | minf.minimize(); 50 | } else { 51 | println!("wrong method provided"); 52 | } 53 | 54 | } 55 | } 56 | // this function returns the solution after minimization 57 | pub fn get_x(&self) -> Vec { 58 | self.x.clone() 59 | } 60 | pub fn set_tolerance(&mut self, t: f64) { 61 | self.tol = t; 62 | } 63 | // set max iteration 64 | pub fn max_iteration(&mut self, i: u32) { 65 | self.max_iter = i; 66 | } 67 | pub fn set_verbosity(&mut self, b: bool) { 68 | self.verbose = b; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/string.rs: -------------------------------------------------------------------------------- 1 | use lbfgsb_sys::string as ffi; 2 | #[inline] 3 | pub fn stringfy(task: &mut [i8]) { 4 | unsafe { 5 | ffi::stringfy_(task.as_mut_ptr()); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate rustimization; 2 | use rustimization::lbfgsb_minimizer::Lbfgsb; 3 | #[test] 4 | fn test(){ 5 | let f = |x:&Vec|{ (x[0]+4.0).powf(2.0)}; 6 | let g = |x:&Vec|{vec![2.0*(x[0]+4.0)]}; 7 | let mut x = vec![40.0f64]; 8 | { 9 | let mut fmin = Lbfgsb::new(&mut x,&f,&g); 10 | fmin.set_upper_bound(0,100.0); 11 | //fmin.set_lower_bound(0,10.0); 12 | fmin.set_verbosity(-1); 13 | fmin.max_iteration(100); 14 | fmin.minimize(); 15 | } 16 | println!("{:?}",x); 17 | } --------------------------------------------------------------------------------